Forum Discussion

Vince_Beltz_959's avatar
Vince_Beltz_959
Icon for Nimbostratus rankNimbostratus
Sep 21, 2011

String Map Fail?

Argh. Can't seem to edit out all that MS crap up there, because I copied this in from an email.

 

 

I'm trying to build a function allowing search-and-replace of substrings within a URI.

 

 

Class:

 

class URI_STRING_REPLACE_LIST {

 

"/coupons/" { "/promotions/offers/coupons/signin.go" }

 

}

 

 

Rule:

 

 

when HTTP_REQUEST {

 

 

set httpuri [string tolower [HTTP:uri]]

 

 

set urisearch ""

 

set urireplace ""

 

set newuri ""

 

set urisearch [class match -name $httpuri contains URI_STRING_REPLACE_LIST]

 

set urireplace [class match -value $urisearch contains URI_STRING_REPLACE_LIST]

 

log local0.info "URI-Replace1 Search: $urisearch Replace: $urireplace"

 

if { ( ( $urisearch ne "" ) and ( $urireplace ne "" ) ) } {

 

set $newuri [string map [list $urisearch $urireplace ] $httpuri]

 

log local0.info "URI-Replace2 New: $newuri URI: [HTTP::uri]"

 

set HTTP::uri $newuri

 

return

 

}

 

 

}

 

 

Log:

 

 

Sep 21 22:08:42 local/tmm5 info tmm5[7234]: Rule URI_STRING_REPLACE : URI-Replace1 Search: /coupons/ Replace: /promotions/offers/coupons/signin.go

 

Sep 21 22:08:42 local/tmm5 info tmm5[7234]: Rule URI_STRING_REPLACE : URI-Replace2 New: URI: /coupons/

 

 

$urisearch and $urireplace are matching, the string map to set $newuri (though I thought I was seeing it work in the logs earlier) is failing. I tried adding list to the string map statement after finding it referred to in another thread here, but it doesn't seem to help. I'd also tried setting HTTP:uri with the string map directly, but added $newuri trying to troubleshoot. Any ideas why string map doesn't seem to work, or something to use instead?

 

5 Replies

  • Original post:

    I'm trying to build a function allowing search-and-replace of substrings within a URI.

     

     

    Class:

     

     

    class URI_STRING_REPLACE_LIST {   "/coupons/" { "/promotions/offers/coupons/signin.go" }}

     

     

     

     

    Rule:

     

     

     

     

    when HTTP_REQUEST {     set urisearch ""    set urireplace ""    set newuri ""    set urisearch [class match -name $httpuri contains URI_STRING_REPLACE_LIST]    set urireplace [class match -value $urisearch contains URI_STRING_REPLACE_LIST]                log local0.info "URI-Replace1 Search: $urisearch Replace: $urireplace"                if { ( ( $urisearch ne "" ) and ( $urireplace ne "" ) ) } {                                set $newuri [string map [list $urisearch $urireplace ] $httpuri]                                log local0.info "URI-Replace2 New: $newuri URI: [HTTP::uri]"                                set HTTP::uri $newuri                                return                } }

     

     

     

     

    Log:

     

     

    Sep 21 22:08:42 local/tmm5 info tmm5[7234]: Rule URI_STRING_REPLACE : URI-Replace1 Search: /coupons/ Replace: /promotions/offers/coupons/signin.go

     

    Sep 21 22:08:42 local/tmm5 info tmm5[7234]: Rule URI_STRING_REPLACE : URI-Replace2 New: URI: /coupons/

     

     

    $urisearch and $urireplace are matching, the string map to set $newuri (though I thought I was seeing it work in the logs earlier) is failing. I tried adding list to the string map statement after finding it referred to in another thread here, but it doesn't seem to help. I'd also tried setting HTTP:uri with the string map directly, but added $newuri trying to troubleshoot. Any ideas why string map doesn't seem to work, or something to use instead?

     

     

     

  • Hi Vince,

     

     

    A few things:

     

     

    1. Prior to v11.0, most HTTP:: command values were cached in the same event. So this example below would modify the URI to /new_uri, but the log commands would both show the original URI:

     

     

    log local0. "1 - URI: [HTTP::uri]"

     

    HTTP::uri "/new_uri"

     

    log local0. "2 - URI: [HTTP::uri]"

     

     

    This was fixed in v11. For past versions, if you want to use the new URI you can save the value to a variable.

     

     

    2. You're using 'set HTTP::uri $newuri'. This would create a new variable named $HTTP::uri. If you want to modify the URI, use 'HTTP::uri $newuri'.

     

     

    3. I don't see where you're defining $httpuri. Is this just a test you're doing instead of using [HTTP::uri]?

     

     

    Aaron
  • Thanks, Hoolio - I updated my post to show a value being set for $httpuri - this is being excerpted from a larger rule. Point taken on set HTTP:uri v. just HTTP:uri, but my main problem seems to be with:

     

     

    set $newuri [string map [list $urisearch $urireplace] $httpuri]

     

     

    (or, all I really want):

     

     

    HTTP::urii [string map [list $urisearch $urireplace] $httpuri]
  • This should work fine:

     

     

    HTTP::uri [string map [list $urisearch $urireplace] $httpuri]

     

     

    If you want to verify the rewrite is done successfully even thought the value for [HTTP::uri] won't show it, you can log the value in a later priority HTTP_REQUEST event. Just add this code to the end of your existing iRule:

     

     

    
    when HTTP_REQUEST priority 501 {
       log local0. "[IP::client_addr]:[TCP::client_port]: 501: Updated \[HTTP::uri\]: [HTTP::uri]"
    }
    

     

     

    Aaron
  • Thanks again for the extra logging tip Hoolio - the rewrite is indeed happening, but I'm not getting the page I should be, so the problem must be elsewhere.