Forum Discussion
URI inspect - Rewrite - Redirect
DevGods
I am trying to inspect URI and Insert into a newly formatted redirect. I am trying to use the URI Interrogation code to dump the params then formulate the redirect.
If I read the code correctly I should be able to dump the query into param format then I FEASIBLY should be able to write a rule that would look something like this correct?
when HTTP_REQUEST {
set namevals [split [HTTP::query] "&"]
for {set i 0} {$i < [llength $namevals]} {incr i} {
set params [split [lindex $namevals $i] "="]
set pnum [expr $i+1]
log local0. "Param[$pnum]: [lindex $params 0]"
log local0. "Value[$pnum]: [URI::query [HTTP::uri] [lindex $params 0]]"
if { [HTTP::uri] starts_with "/receiptLocator" } {
HTTP::redirect "https://my.domain.com/ReceiptLocator=$pnum1&CityOrigin=$pnum2&FirstName=$pnum3&LastName=$pnum4"
Incoming URI I will inspect
receiptLocator=ABCDEF&originCity=BOS&firstName=John&lastName=Doe&language=en
Rewritten and Redirected URI
ReceiptLocator=ABCDEF&CityOrigin=BOS&FirstName=John&LastName=Doe
4 Replies
- StephanManthey
Nacreous
Your sample code loops through all query parameters and would send a redirect per parameter (as there is no closing curly bracket before doing the redirect).
To make the code more rubust I would not count on the expected order of parameters. A jump table (switch) may help to assign the proper value to each parameter. - StephanManthey
Nacreous
You can try the following code, please:
when HTTP_REQUEST { if {[HTTP::query] ne "" && !([HTTP::query] starts_with "ReceiptLocator") } { set namevals [split [HTTP::query] "&"] log local0. "[HTTP::query]; number of params: <[llength ${namevals}]>" for {set i 0} {$i < [llength ${namevals}]} {incr i} { set param [split [lindex ${namevals} $i] "="] log local0. "current parameter: <$param>, <${i}> of <[llength ${namevals}]>" log local0. "param_name: <[lindex $param 0]>, param_value <[lindex $param 1]>" switch [string tolower [lindex $param 0]] { "receiptlocator" { set ReceiptLocator [lindex $param 1] } "origincity" { set CityOrigin [lindex $param 1] } "firstname" { set FirstName [lindex $param 1]} "lastname" {set LastName [lindex $param 1]} } } if { [info exists ReceiptLocator] && [info exists CityOrigin] && [info exists FirstName] && [info exists LastName] } { HTTP::redirect "HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::path]?ReceiptLocator=${ReceiptLocator}&CityOrigin=${CityOrigin}&FirstName=${FirstName}&LastName={LastName}" } else { log local0. "missing parameters" } } else { log local0. "no query data or query already in expected format" } } - nitass
Employee
this is just another example.
configuration [root@ve11a:Active:In Sync] config tmsh list ltm virtual bar ltm virtual bar { destination 172.28.24.10:80 ip-protocol tcp mask 255.255.255.255 pool foo profiles { http { } tcp { } } rules { qux } source 0.0.0.0/0 source-address-translation { type automap } vs-index 2 } [root@ve11a:Active:In Sync] config tmsh list ltm rule qux ltm rule qux { when RULE_INIT { set static::param {receiptLocator originCity firstName lastName} set static::newparam {ReceiptLocator CityOrigin FirstName LastName} set static::len [llength $static::param] } when HTTP_REQUEST { if { [HTTP::uri] starts_with "/receiptLocator" } { set newuri "/" for {set i 0} {$i < $static::len} {incr i} { set pvalue [URI::query "?[string trimleft [HTTP::uri] /]" [lindex $static::param $i]] if { $newuri ne "/" } { append newuri "&" } append newuri "[lindex $static::newparam $i]=$pvalue" } HTTP::redirect "http://[HTTP::host]$newuri" } else { do nothing } } } test [root@ve11a:Active:In Sync] config curl -i "http://172.28.24.10/receiptLocator=ABCDEF&originCity=BOS&firstName=John&lastName=Doe&language=en" HTTP/1.0 302 Found Location: http://172.28.24.10/ReceiptLocator=ABCDEF&CityOrigin=BOS&FirstName=John&LastName=Doe Server: BigIP Connection: Keep-Alive Content-Length: 0 - StephanManthey
Nacreous
I noticed a mistake in my first sample (missing variable declaration in response definition).
(For whatever reason I cannot change the previous post.)
Here is the corrected code including a switch for turning debugging on/off and allowing both ampersand and semicolon for parameter separation in query:when HTTP_REQUEST { enable (1), disable (0) debugging set debug 0 if {[HTTP::query] ne "" && !([HTTP::query] starts_with "ReceiptLocator") } { split query into parameters separated by semicolon or ampersand set namevals [split [HTTP::query] ";&"] if { $debug > 0 } { log local0. "original query: <[HTTP::query]>; number of params: <[llength ${namevals}]>" } loop through all parameters for {set i 0} {$i < [llength ${namevals}]} {incr i} { read parameter name and value set param [split [lindex ${namevals} $i] "="] if { $debug > 0 } { log local0. "current parameter: <$param>, <[expr {${i} + 1}]> of <[llength ${namevals}]>" log local0. "param_name: <[lindex $param 0]>, param_value <[lindex $param 1]>" } assign variable values for redirect switch [string tolower [lindex $param 0]] { "receiptlocator" { set ReceiptLocator [lindex $param 1] } "origincity" { set CityOrigin [lindex $param 1] } "firstname" { set FirstName [lindex $param 1]} "lastname" {set LastName [lindex $param 1]} } } redirect only if variables are set if { [info exists ReceiptLocator] && [info exists CityOrigin] && [info exists FirstName] && [info exists LastName] } { HTTP::redirect "HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::path]?ReceiptLocator=${ReceiptLocator}&CityOrigin=${CityOrigin}&FirstName=${FirstName}&LastName=${LastName}" } else { if { $debug > 0 } { log local0. "missing parameters in query" } } } else { if { $debug > 0 } { log local0. "no query data or query already in expected format" } } }For testing locally on the F5 device I´m using the same approach as Nitass:
curl -i http://10.131.131.120/test?receiptLocator=ABCDEF\;originCity=BOS\;firstName=John\&lastName=Doe\;language=en HTTP/1.0 302 Found Location: HTTP::redirect https://10.131.131.120/test?ReceiptLocator=ABCDEF&CityOrigin=BOS&FirstName=John&LastName=Doe Server: BigIP Connection: Keep-Alive Content-Length: 0
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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