Forum Discussion
ssl_b0y_87395
Nimbostratus
Jul 18, 2011Collapsing Lots of URIs into one with 2 Irules
Hi
Long time-lurker, first time poster! We've got a customer who'd been using F5 for some time for tactical LTM stuff, when "from high" a requirement came to collapse their six or seven web applications into a single, uniform URL and move the static web-content to the "parent" organisations website. Physically doing this was just impossible given the logistics of three distinct web farms physically in three different locations, for various reasons.
I knew enough about irules to know that the F5 could make this happen, but I didn't have time to fudge about trying to get it to work so we engaged F5 PS to put together a solution for us. Essentially some URLS are proxied, some directed to local pools and some are straight redirects. There is a mix of HTTP and HTTPS, some applications available in both, some only in HTTPS. After 2 days of hair pulling and teeth gnashing we have a solution, which thus far works. I've obfuscated the code as much as possible, but hopefully it still makes sense..Apologies for the lack of comments in the code; it's how F5 PS supplied it :) I've had to make a couple of tweaks as additional requirements have dropped out of the woodwork, but it's a pretty much as it came..
It's been 15 years since I've done any programming in anger, my knowledge of f5 and irules comes entirely from DevCentral..So I'm posting this for the benefit of others and would be interested in any feedback, good, bad, indifferent!
Attached to the HTTP VS:
when HTTP_REQUEST {
Pull out a specific URL and change the host headers to send to the default pool (server-side HH logic in this case)
string tolower [HTTP::host]
if { [HTTP::host] contains "bl.newurl.co.uk"} {HTTP::header replace Host bl.oldurl.co.uk}
Otherwise this is the main Primary URL
Anyone accessing the root will be directed back out to the parent site
Anyone Accessing any of the nominated "applications" will be redirected to the HTTPS VS and the PATH appended.
Everything else, send to the default Pool but change to host header so the site accepts it and presents the correct content.
else {
switch -glob [string tolower [HTTP::path]] {
"/" { HTTP::redirect http://www.parentorg.co.uk/division }
"/favicon.ico" { HTTP::respond 404 }
"/intenrnalapp1*" -
"/externalapp1*" -
"/externalapp2*" -
"/externalapp3*" { HTTP::redirect https://www.newurl.co.uk[HTTP::uri] }
default { HTTP::header replace Host www.oldurl.co.uk }
}
}
}
when HTTP_RESPONSE {
re-write the responses to take out the refereces to the various old URLs/file locations and insert the new ones.
STREAM::disable
if { [HTTP::is_redirect] } {
if { [HTTP::header Location] starts_with "http" } {
HTTP::header replace Location [string map "[URI::host [HTTP::header Location]] www.newurl.co.uk" [HTTP::header Location]]
}
} elseif { [HTTP::header Content-Type] starts_with "text" } {
STREAM::expression {@www.oldurl.co.uk@www.newurl.co.uk@@www.oldurl2.co.uk@www.newurl.co.uk@@bl.oldurl.co.uk@bl.newurl.co.uk@@}
STREAM::enable
}
}
2 Replies
- ssl_b0y_87395
Nimbostratus
And the one which is attached to the SSL VS:
when HTTP_REQUEST {
Do a force redirect anyone access the root
Match the Paths to the various applications URLs
Re-write the headers so back-end server still thinks it recieving "legacy" client requests
Internalapp2 is not a public website and has an additional white list for live and test variations
Final piece is to do with that there are two slight variations of the external app, essentially different branding paths to the same location
switch -glob [string tolower [HTTP::path]] {
"/" { HTTP::redirect http://www.parentcompany.co.uk/division }
"/AP1*" {
SSL::disable serverside
pool pool_internalapp1
HTTP::header replace Host ap1.oldurl.co.uk
if { [string tolower [HTTP::path]] eq "/ap1" } {
HTTP::path "/"
} else {
HTTP::path [string range [HTTP::path] 4 end]
}
}
"/internalapp2_test*" {
if { [class match [IP::client_addr] equals "Whitelisted_IPs"] } {
SSL::disable serverside
pool pool_Internalapp2_test
HTTP::header replace Host internalapp2-test.oldurl.co.uk
HTTP::path [string map { /internalapp2_test /app2_root } [HTTP::path]]
} else {
HTTP::redirect http://www.parentcompany.co.uk/division
}
}
"/internalapp2*" {
if { [class match [IP::client_addr] equals "Whitelisted_IPs"] } {
SSL::disable serverside
pool Pool_Internalapp2
HTTP::header replace Host internalapp2.oldurl.co.uk
HTTP::path [string map { /internalapp2 /app2_root } [HTTP::path]]
} else {
HTTP::redirect http://www.parentcompany.co.uk/division
}
}
"/favicon.ico" { HTTP::respond 404 }
"/*" {
pool Pool_externalhost_SSL
HTTP::header replace Host www.oldurl.co.uk
if { [string tolower [HTTP::path]] starts_with "/externalapp2" } {
HTTP::path [string map { /externalapp2 /externalapp2CS } [HTTP::path]]
set map_externalapp2 1
} else {
set map_externalapp2 0
}
}
}
}
when HTTP_RESPONSE {
Re-write the HEADERS as they come back, directing HTTP to HTTPs and inserting the New URL to make sure the links work properly
set header_var [HTTP::header "Referer"]
STREAM::disable
switch [LB::server pool] {
"Pool_Internalapp2" {
if { [HTTP::is_redirect] } {
HTTP::header replace Location [string map {http https /app2_root /internalapp2 internalapp2.oldurl.co.uk www.newurl.co.uk} [HTTP::header Location]]
log local0. "Found a redirect, directing to =$header_var"
} elseif { [HTTP::header Content-Type] starts_with "text" } {
STREAM::expression {@/app2_root@/internalapp2@}
STREAM::enable
}
}
"pool_Internalapp2_test" {
if { [HTTP::is_redirect] } {
HTTP::header replace Location [string map {http https /app2_root /internalapp2_test internalapp2-test.oldurl.co.uk www.newurl.co.uk} [HTTP::header Location]]
} elseif { [HTTP::header Content-Type] starts_with "text" } {
STREAM::expression {@/app2_root@/internalapp2_test@}
STREAM::enable
}
}
"Pool_externalhost_SSL" {
if { [HTTP::is_redirect] } {
if { [HTTP::header Location] starts_with "http" } {
HTTP::header replace Location [string map "[URI::host [HTTP::header Location]] www.newurl.co.uk" [HTTP::header Location]]
if { [URI::path [HTTP::header Location]] starts_with "/externalapp2" || [URI::path [HTTP::header Location]] starts_with "/externalapp2CS" } {
if { [URI::protocol [HTTP::header Location]] eq "http" } {
HTTP::header replace Location [string map {http https} [HTTP::header Location]]
}
}
}
} elseif { [HTTP::header Content-Type] starts_with "text" } {
if { $map_externalapp2 } {
STREAM::expression {@/externalapp2CS@/externalapp2@@www.oldurl.co.uk@www.newurl.co.uk@@www.oldurl2.co.uk@www.newurl.co.uk@}
} else {
STREAM::expression {@www.oldurl.co.uk@www.newurl.co.uk@@www.oldurl2.co.uk@www.newurl.co.uk@}
}
STREAM::enable
}
if { $map_externalapp2 } {
if { [HTTP::is_redirect] } {
HTTP::header replace Location [string map {/externalapp2CS /externalapp2} [HTTP::header Location]]
}
}
unset map_externalapp2
}
pool_internalapp1 {
if { [HTTP::is_redirect] } {
if { [HTTP::header Location] starts_with "/" } {
HTTP::header replace Location "/AP1[HTTP::header Location]"
} elseif { [HTTP::header Location] starts_with "http" } {
HTTP::header replace Location [string map "[URI::host [HTTP::header Location]] www.newurl.co.uk/AP1" [HTTP::header Location]]
}
} elseif { [HTTP::header Content-Type] starts_with "text" } {
STREAM::expression {@src='/@src='/AP1/@@src="/@src="/AP1/@@action='/@action='/AP1@@action="/@action="/AP1@@href='/@href='/AP1@@href="/@href="/AP1@}
STREAM::enable
}
}
}
} - Chris_Miller
Altostratus
Haven't read it yet but saw on Twitter that you'd posted it. Thanks!
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects