Forum Discussion

shiyanfeng_1265's avatar
shiyanfeng_1265
Icon for Nimbostratus rankNimbostratus
Jul 01, 2016

What is the meaning of this irules

when HTTP_RESPONSE { if { [HTTP::header exists "Location"] } { set protocol_host [substr [HTTP::header "Location"] 0 ":9081"] set remainder [substr [HTTP::header "Location"] [expr {[string length $protocol_host] + 5}]] HTTP::header replace "Location" $protocol_host$remainder } }

 

4 Replies

  • when you receive a response from a backend server

     

    if the respond is 30x location (redirection)

     

    we take the location value without port :9081

     

    we take whatever is after the host and port (uri)

     

    we replace the value redirection host + Uri

     

    basically that is changing the redirection by removing the port 9081.

     

  • Re-adding it with formatting:

     

    when HTTP_RESPONSE { 
        if { [HTTP::header exists "Location"] } { 
            set protocol_host [substr [HTTP::header "Location"] 0 ":9081"] 
            set remainder [substr [HTTP::header "Location"] [expr {[string length $protocol_host] + 5}]] 
            HTTP::header replace "Location" $protocol_host$remainder 
         } 
     }
    

     

    This event fires when the BIG-IP receives an HTTP Response message (when HTTP_RESPONSE). The rule performs logic if the HTTP Response message contains a header named Location (HTTP::header exists "Location") -- which generally means that the Response Code is a 3xx series (redirection). The format of a Location header is either a URL or a URI fragment. This code seems to assume it is a URL of the form ://host:9081. It extracts the ://host portion and assigns it to the variable protocol_host (set protocol_host [substr ...]). It then assigns the portion to the variable remainder (set remainder [substr ...]). Finally, it replaces the Location header value with the extracted protocol_host and remainder.

    In short, this rule appears to be simply removing the explicit port from the URL provided in the Location header. There are alternative mechanisms, e.g.:

     

    when HTTP_RESPONSE {
        if { [HTTP::header exists Location] } {
            if { [scan [HTTP::header Location] {%[^:]:%[^:]:%d%s} proto host port urifragment] == 4 } {
                HTTP::header replace Location "$proto:$host$urifragment"
            }
        }
    }
    

     

    This alternative has the slight advantage of being port number agnostic, and the possibly more useful advantage of not chopping off the scheme if the Location header does not contain an explicit port (which would happen in your provided code). It is also almost certainly faster. However, as is generally the case with Tcl, there's more than one way to tackle this problem.