Forum Discussion

tarsier_90410's avatar
tarsier_90410
Icon for Nimbostratus rankNimbostratus
Oct 17, 2011

HTTP::respond - bug or improper use?

When using HTTP::respond 302 Location "https://<...>" in the HTTP_RESPONSE when the server also issued a 302, the LTM's 302 does not appear to work and the client receives the location specified by the server.

 

 

Shouldn't the use of HTTP::respond cause the server response to be discarded? When I do something similar with HTTP::respond 200, the entire server response appears to be dropped.

 

 

 

 

 

 

 

 

 

  • Hi tarsier,

    I would like to verify your findings. Can you be more specific on how you implemented your HTTP::respond and it didn't work?

    I tried the following against a web page that was trying to specifically do a 302 and my iRule overrode it.

    
    when HTTP_REQUEST {
    if { [string tolower [HTTP::uri]] starts_with "/redirect" } {
    HTTP::respond 302 Location "http://google.com"
    }
    }
    
  • The significant difference is that I am doing the redirect in the HTTP_RESPONSE event, and also setting cookies, for a server response that sets a particular header...

    
    when HTTP_RESPONSE {
    if { [HTTP::header exists "status"] } {
    switch [HTTP::header value "status"] {
    "OK" {
    HTTP::respond 302 Location "https://$HOSTNAME$URI" "Set-Cookie" $MY_COOKIE
    return
    }
    ... other cases ...
    default {
    
    }
    }
    }
    }
    

    The switch case works fine, but the HTTP::respond does not. I have tried hard coding the Location value and cookie value strings, but it makes no difference.
  • LOL. I got a good laugh out of that. No wonder it worked so well 🙂

    There is no status value in the HTTP::header, you will need to use [HTTP::status].

    If you wish to see your headers use this iRule to verify:

     
    when HTTP_REQUEST {
    set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]"
    log local0. "============================================="
    log local0. "$LogString (request)"
    foreach aHeader [HTTP::header names] {
    log local0. "$aHeader: [HTTP::header value $aHeader]"
    }
    log local0. "============================================="
    }
    when HTTP_RESPONSE {
    log local0. "============================================="  foreach aHeader [HTTP::header names] {
    log local0. "$aHeader: [HTTP::header value $aHeader]"
    }
    log local0. "============================================="
    http://devcentral.f5.com/wiki/iRules.LogHttpHeaders.ashx
    }
    
  • Sorry for the confusion, but the "status" header is being inserted by our java developers in the app, and I am not confusing it with the HTTP status. We could make it any name but "status" is what they chose. I can see the "OK" branch of the switch block is executing if I add a log statement, it's just that the HTTP::respond appears to have no effect.
  • Interesting.

    I replicated what you have as closely as possible and can only suggest that you set the values to a known state and string tolower your values. This is a sample of what I tested and it worked, so there is some other detail that I am missing from being able to replicate your issue.

    
    when HTTP_RESPONSE {
    if { [string tolower [HTTP::header exists "server" ]] } {
    switch [string tolower [HTTP::header value "server" ]] { 
    "microsoft-iis/6.0" { HTTP::respond 302 Location "https://www.google.com" }
    }
    }
    }
    
  • it seemed working fine in my lab. is there anything i missed?

    [root@iris:Active] config  b virtual bar list
    virtual bar {
       snat automap
       pool foo
       destination 172.28.17.33:http
       ip protocol tcp
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@iris:Active] config  b pool foo list
    pool foo {
       members 10.10.70.110:http {}
    }
    [root@iris:Active] config  b rule myrule list
    rule myrule {
       when HTTP_RESPONSE {
            if {[HTTP::header exists "status"]} {
                    switch [HTTP::header value "status"] {
                            "OK" {
                                    HTTP::respond 302 Location "http://www.google.com" "Set-Cookie" "test"
                            }
                            default {  do something }
                    }
            }
    }
    }
    
    [root@iris:Active] config  curl -I http://10.10.70.110
    HTTP/1.1 200 OK
    Date: Tue, 18 Oct 2011 00:10:01 GMT
    Server: Apache/2.0.59 (rPath)
    Last-Modified: Sat, 11 Jun 2011 00:31:47 GMT
    ETag: "667a-67-cfb682c0"
    Accept-Ranges: bytes
    Content-Length: 103
    Vary: Accept-Encoding
    status: OK
    Content-Type: text/html; charset=UTF-8
    
    [root@iris:Active] config  curl -I http://172.28.17.33
    HTTP/1.0 302 Found
    Location: http://www.google.com
    Set-Cookie: test
    Server: BigIP
    Connection: Keep-Alive
    Content-Length: 0