Forum Discussion
DNSgeek_90802
Nimbostratus
Dec 28, 2009Get HTTP::uri in HTTP_RESPONSE
I have an irule that needs to get the URI from a 404 page and muck with it. However, when I try to reference [HTTP::uri], I get told that I cannot access it from the HTTP_RESPONSE context.
How can I get the URI that caused the 404 so I can modify it?
Thanks!
Tom
- The_Bhattman
Nimbostratus
Hi Tom, - hoolio
Cirrostratus
You can save the HTTP::uri value in HTTP_REQUEST to a variable and then reference that in HTTP_RESPONSE:when HTTP_REQUEST { Save the URI set uri [HTTP::uri] } when HTTP_RESPONSE { Check if response was a 404 if {[HTTP::status] == 404}{ log local0. "[IP::client_addr]:[TCP::client_port]: 404 received from $uri" } }
- hoolio
Cirrostratus
A variable set in a prior event should be available in all subsequent events on the same TCP connection. The only case I can think of where you'd get a runtime TCL error about a variable not existing is if you added the iRule in the middle of a client's TCP connection. Any new TCP connection should work fine. - DNSgeek_90802
Nimbostratus
Here's what I'm trying to do. I send a request to pool A. If and only if pool A returns a 404 code, I need to rewrite the path and send the request to pool B. No matter what pool B responds with, return it to the client.when HTTP_RESPONSE { if { $::DEBUG }{ log "respcode -> [HTTP::status]'" log "host -> [HTTP::host]" } if { ([HTTP::status] == 404) } { if { $mypath ends_with "/" }{ set mypath [string range 0 [string length $mypath]-1 $mypath] append .html $mypath } HTTP::path $mypath if { $::DEBUG }{ log "retruri -> $mypath" } pool B } }
HTTP::path $mypath
01070151:3: Rule [myrule] error: line 34: [command is not valid in current event context (HTTP_RESPONSE)] [HTTP::path $mypath]
- hoolio
Cirrostratus
Ah, so that error is because the HTTP::path command is not valid in the HTTP_RESPONSE event. There isn't a URI or path in responses.Based on the example on the HTTP::request wiki page: http://devcentral.f5.com/wiki/default.aspx/iRules/http__retry.html when CLIENT_ACCEPTED { Initialize a variable to track whether a request has been retried set retries 0 } when HTTP_REQUEST { Check if request is a GET (we only save the request headers using HTTP::request) if {[HTTP::method] eq "GET"}{ Save the request headers set request_headers [HTTP::request] log local0. "HTTP request headers: $request_headers" } } when LB_SELECTED { if { $retries >= 1 } { LB::reselect pool pool_b } } when HTTP_RESPONSE { if { [HTTP::status] == 404 } { incr retries log local0. "4xx error caught: retry $retries out of [active_members [LB::server pool]]" if { $retries < [active_members [LB::server pool]] } { HTTP::retry $request_headers } } else { Successful response, reset the retries variable set retries 0 } }
- DNSgeek_90802
Nimbostratus
How would I modify the HTTP::path in the retry? I need to be able to try pool A, if pool A 404's, modify the path and try again with pool B using the new path. - hoolio
Cirrostratus
Sorry, I forgot about that part. Can you try this?Based on the example on the HTTP::request wiki page: http://devcentral.f5.com/wiki/default.aspx/iRules/http__retry.html when CLIENT_ACCEPTED { Initialize a variable to track whether a request has been retried set retries 0 } when HTTP_REQUEST { Use pool A by default pool pool_A Check if this is a retried request if { $retries == 0 }{ Check if request is a GET (we only save the request headers using HTTP::request) if {[HTTP::method] eq "GET"}{ Save the request headers set request_headers [HTTP::request] log local0. "HTTP request headers: $request_headers" } } else { This is a retry, so check if the path ends with a slash if { [HTTP::path] ends_with "/" }{ Remove the last slash and append .html to the path HTTP::path "[string range [HTTP::path] 0 end-1].html" } } } when LB_SELECTED { if { $retries >= 1 }{ LB::reselect pool pool_b } } when HTTP_RESPONSE { if { [HTTP::status] == 404 }{ incr retries log local0. "4xx error caught: retry $retries out of [active_members [LB::server pool]]" if { $retries < [active_members [LB::server pool]] }{ HTTP::retry $request_headers } } else { Successful response, reset the retries variable set retries 0 } }
- DNSgeek_90802
Nimbostratus
You rock dude. Thanks a bunch.- AhmedGalal219_3
Nimbostratus
accept his answer if it work
- Kiran_373035
Nimbostratus
Hey Hooli,
Is there another way to record the URI in the response header? Coz in our environment, redirection rule is set on server and URL masking requirement is planned at F5. I cannot record the URI from request header. Please help me with this
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects