For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Joseph_Lindsly's avatar
Dec 08, 2015

HTTP redirect with different URIs

Hi,

I have a request to redirect traffic from http://www.abc.com/sites/pmo to http://www.xyz.com/is/pmo. The customer wants all deep links past pmo to work. I tried the below irule, but it is not working.

    when HTTP_REQUEST {
if  { [HTTP::uri] contains "/sites/pmo"} {
   HTTP::redirect "http://www.xyz.com/is/pmo/[string range [URI::query "?&[HTTP::query]" pmo/] 0 300]"
 }
}

Any help would be appreciated.

Thanks, Joe

5 Replies

  • Hi Joe,

    you may try this snipped...

    when HTTP_REQUEST {
        if  { [HTTP::uri] contains "/sites/pmo"} {
            HTTP::redirect "http://www.xyz.com/is[string range [HTTP::uri] 6 end]"
        }
    }
    

    Cheers, Kai

  • Hi,

    when HTTP_REQUEST {
        if  { [HTTP::path] starts_with "/sites/pmo"} {
            HTTP::redirect "http://www.xyz.com[string map {/sites/pmo /is/pmo} [HTTP::path]]&[HTTP::query]"
             or if the path is only  
            HTTP::redirect "http://www.xyz.com/is/pmo&[HTTP::query]"
        }
    }
    

    or if the path is /sites/pmo and not all URL starting with /sites/pmo:

        when HTTP_REQUEST {
        if  { [HTTP::path] quals "/sites/pmo"} {
            HTTP::redirect "http://www.xyz.com/is/pmo&[HTTP::query]"
        }
    }
    
  • Hey Stanislas,

     

    i like to comment your provided snippets...

     

    1st snippet:

     

    [HTTP::path] and [HTTP::query] seems to perform an ordinary [getfield [HTTP::uri] "?" (1|2)] in the background. In the end your snippet is splitting [HTTP::uri] two times followed by a substitution to produce a string comparable with [HTTP::uri] but seperated by a "&" sign (i dont understand the "&" sign at all, since the URL seperator between PATH and QUERY is always the "?" letter).

     

    Then you use a [string map] on the substituted string to change the leading part. Well, [string map] is a very powerfull command to scan and replace (one or many) contents somewhere within string. But if the content to be replaced is at the beginning then [string range] in combination with subtitution does performance wise a somewhat better job.

     

    2nd snippet:

     

    Contains also a "&" sign as seperator between PATH and QUERY. See discription above.

     

    Cheers, Kai

     

  • Kai, You're right. the "&" must be replaced by "?" in the irule...

     

    For the "string range" vs "string map", I'm no sure is it better to use string range. I checked performance of tcl code with tclsh:

     

    -- Provisioning of variables:

     

    % set uri "/sites/pmo?test=toto&foo=bar"
    /sites/pmo?test=toto&foo=bar
    % set path /sites/pmo
    /sites/pmo
    % set query "test=toto&foo=bar"
    test=toto&foo=bar

    -- Test of code:

     

    % set new_uri "http://www.xyz.com/is[string range $uri 6 end]"
    http://www.xyz.com/is/pmo?test=toto&foo=bar
    % set new_uri "http://www.xyz.com[string map {/sites/pmo /is/pmo} $path]?$query"
    http://www.xyz.com/is/pmo?test=toto&foo=bar

    -- Performance of string range:

     

    % time { set new_uri "http://www.xyz.com/is[string range $uri 6 end]"} 10000
    2.9012927 microseconds per iteration
    % time { set new_uri "http://www.xyz.com/is[string range $uri 6 end]"} 10000
    2.9444715 microseconds per iteration

    -- Performance of string map:

     

    % time {set new_uri "http://www.xyz.com[string map {/sites/pmo /is/pmo} $path]?$query"} 10000
    2.8971892 microseconds per iteration
    % time {set new_uri "http://www.xyz.com[string map {/sites/pmo /is/pmo} $path]?$query"} 10000
    2.9607483 microseconds per iteration

    But I agree that your code does not add a "?" if there is no query string.

     

  • Hi Stanislav,

     

    did some old fashioned "timing on" test, since "time 10000" would chain the commands in a non-realistic fashion and may cause the CPU to cache certain things just too good. You may have seen this before, that the more iteration you launch the faster the code will get.

     

    To avoid this type of caching I tend to execute some rather complex TCL code before each test iteration.

     

    Timing using [string range] in combination with [HTTP::uri]

     

    when HTTP_REQUEST timing on priority 200 {
        set temp(result) "http://www.xyz.com/is[string range [HTTP::uri] 6 end]"
    }
    
    • Request : 100
    • Min Cycles: 9243
    • Avg Cycles: 12670
    • Max Cycles: 21267

    Timing using [string map] in combination with [HTTP::uri]

     

    when HTTP_REQUEST timing on priority 200 {
        set temp(result) "http://www.xyz.com[string map {/sites/pmo /is/pmo} [HTTP::uri]]"
    }
    
    • Request : 100
    • Min Cycles: 14517
    • Avg Cycles: 18861
    • Max Cycles: 27999

    Timing using [string map] in combination with [HTTP::path] and [HTTP::query]

     

    when HTTP_REQUEST timing on priority 200 {
        set temp(result) "http://www.xyz.com[string map {/sites/pmo /is/pmo} "[HTTP::path]?[HTTP::query]"]"
    }
    
    • Request : 100
    • Min Cycles: 16092
    • Avg Cycles: 22116
    • Max Cycles: 37719

    BTW: URI used for all Tests: /sites/pmo/abc/abc/abc/abc?xyz1=1&xyz2=2

     

    Update: Performed a second "timing on" for every snipped and updated the numbers. The reason for that was that i strongly belive that my chrome browser was asking for /favicon.ico on half of the requests... 😉

     

    Cheers, Kai