Forum Discussion
HTTP Path Modification and Response Rewrite
I have a VIP which is hosting multiple versions of the same application: the current version (/APP_APP1153/APP1153.ashx)is sent to the pool configured on the VS, /G1/APP_APP1153/APP1153.ashx is sent to a G1 pool, and /G2/APP_APP1153/APP1153.ashx is sent to a G2 pool. The issue I am having is the response arriving at the client has /APP_APP1153/APP1153.ashx in the path, so subsequent requests are being send to the pool configured on the VS rather the G1 or G2 pools.
The VS is configured with both a client and server SSL profile (SSL offloading). I am trying to rewrite the HTTP_RESPONSE_DATA, but I have not yet been successful.
The rewrite should be as follows:
- Client sends /G1/APP_APP1153/APP1153.ashx, the iRule modifies the path to /APP_APP1153/APP1153.ashx, the server responds with /APP_APP1153/APP1153.ashx, and the iRule replaces /APP_APP1153/APP1153.ashx to /G1/APP_APP1153/APP1153.ashx before sending the data to the client.
- Client sends /G2/APP_APP1153/APP1153.ashx, the iRule modifies the path to /APP_APP1153/APP1153.ashx, the server responds with /APP_APP1153/APP1153.ashx, and the iRule replaces /APP_APP1153/APP1153.ashx to /G2/APP_APP1153/APP1153.ashx before sending the data to the client.
Currently, the page is not loading and Firefox is reporting "Secure Connection Failed". I see the GET request in Firefox Developer tools, but I do not see a response. I suspect the issue is in the rewrite, but cannot pinpoint the root cause.
Any help would be appreciated.
This is the iRule I have configured on the VS.
when HTTP_REQUEST {
switch [HTTP::path] {
"/G1/APP_APP1153/APP1153.ashx" {
HTTP::cookie remove "app1153"
HTTP::cookie remove "ASP.NET_SessionId"
pool app-g1_443_pool
persist cookie insert app1153
HTTP::path "/TCM_TCM1153/TCM1153.ashx"
set ::group1 1
}
"/G2/TCM_TCM1153/TCM1153.ashx" {
HTTP::cookie remove "app1153"
HTTP::cookie remove "ASP.NET_SessionId"
pool app-g2_443_pool
persist cookie insert app1153
HTTP::path "/APP_APP1153/APP1153.ashx"
set ::group2 1
}
}
}
when HTTP_RESPONSE {
if { $::group1 } {
collect response data
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 4294967295
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
}
elseif { $::group2 } {
collect response data
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 4294967295
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
}
}
when HTTP_RESPONSE_DATA {
if { $::group1 } {
set find "/APP_APP1153/APP1153.ashx"
set replace "/G1/APP_APP1153/APP1153.ashx"
set offset 0
set diff [expr [string length $replace] - [string length $find]]
Get indices of all instances of find string in the payload
set indices [regexp -all -inline -indices $find [HTTP::payload]]
foreach idx $indices {
set start [expr [lindex $idx 0] + $offset]
set end [expr [lindex $idx 1] + $offset]
set len [expr {$end - $start + 1}]
replace the instance of find with the contents of replace
HTTP::payload replace $start $len $replace
modify offset if the replace string is larger or smaller
than find.
incr offset $diff
}
}
elseif { $::group2 } {
set find "/APP_APP1153/APP1153.ashx"
set replace "/G2/APP_APP1153/APP1153.ashx"
set offset 0
set diff [expr [string length $replace] - [string length $find]]
Get indices of all instances of find string in the payload
set indices [regexp -all -inline -indices $find [HTTP::payload]]
foreach idx $indices {
set start [expr [lindex $idx 0] + $offset]
set end [expr [lindex $idx 1] + $offset]
set len [expr {$end - $start + 1}]
replace the instance of find with the contents of replace
HTTP::payload replace $start $len $replace
modify offset if the replace string is larger or smaller
than find.
incr offset $diff
}
}
}
- Lee_SutcliffeNacreous
Good evening..
Seems to me you just want to rewrite URI between client and server. This can be done with [HTTP::uri] no need to collect the HTTP payload and complicated string replacement.
I've just put this very basic iRule together with should illustrate my thinking. I'm just setting a flag on HTTP request so that we know what to change the URI back to on response. Hopefully it might give you some ideas:
when HTTP_REQUEST { set uri "/APP_APP1153/APP1153.ashx" set g1 0 set g2 0 if {[HTTP::uri] equals "/G1/$uri" } { [HTTP::uri] $uri set g1 1 } if {[HTTP::uri] equals "/G2/$uri" } { [HTTP::uri] $uri set g2 1 } } when HTTP_RESPONSE { if {$g1} { [HTTP::uri] "/G1/$uri" } if {$g2} { [HTTP::uri] "/G2/$uri" } } PS - I've not tested this (making the most of a delayed train! )
- Stanislas_Piro2Cumulonimbus
You can try this code (not tested) with a stream profile assigned to the virtual server
when HTTP_REQUEST { set uri "/APP_APP1153/APP1153.ashx" set g1 0 set g2 0 disable compression to support stream profile HTTP::header remove "Accept-Encoding" if {[HTTP::uri] equals "/G1$uri" } { [HTTP::uri] $uri set stream_expression "@$uri@/G2$uri@" set baseURI /G1 } if {[HTTP::uri] equals "/G2$uri" } { [HTTP::uri] $uri set stream_expression "@$uri@/G2$uri@" set baseURI /G2 } } when HTTP_RESPONSE { if { [HTTP::status] == 302 { This is a 302 redirect with a absolute Location URI if {[scan [HTTP::header Location] {%[^:]://%[^/]%s} location_proto location_host location_uri] == 3} { The Location header is absolute URI HTTP::header replace Location $location_proto://$location_host$baseURI$uri } else { The Location header is absolute URI HTTP::header replace Location $baseURI[HTTP::header Location] } } elseif {[HTTP::header value Content-Type] starts_with "text"} { Apply stream expression stored in RULE_INIT event if {$stream_profile_enabled} { STREAM::expression $stream_expression Enable the stream filter for this response only STREAM::enable } } }
Recent Discussions
Related Content
* 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