Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

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.




1
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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"
	}
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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 {
				<stuff>
			}
		}
	}
}


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.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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.
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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" }
		}
	}
}
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
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

0