Forum Discussion

Gerardo_Garcia_'s avatar
Gerardo_Garcia_
Icon for Nimbostratus rankNimbostratus
Apr 08, 2008

URI conditional collecting

We are trying to replace redirects done by meta refresh with proper 302s. We are using the following example:

 

 

http://devcentral.f5.com/Wiki/default.aspx/iRules/Replace_HTTP_Refresh_With_HTTP_Redirect.html

 

 

However, this only happens during login, and we would like to trim the number of responses that we are collecting and examining for meta tags. One marker is that the request url contains ".pt?"

 

 

When we modify the HTTP_RESPONSE to ignore other urls by examining HTTP::uri, we get "command is not valid in current event context".

 

 

While I am sure that not being able to determine the uri of the response you are looking at follows all logic and makes perfect sense to the experts, it is rather baffling and frustrating for us first-timers.

 

 

We could use some help getting around this. We have poked around the samples, but to no avail. I assume we will need to watch some other event and set a variable, but we are not fluent in iRules and could use a hand.

 

 

Below is our current implementation, error and all. We only block chunking if the url has the ".pt?" flag, and are only interested if the content length is between 400 and 600. Else, it is not going to be a meta refresh and there is no need to collect.

 

 

Any help is appreciated.

 

 

iRule to convert meta refresh statements to 302s

 

when HTTP_REQUEST {

 

Don't allow data to be chunked if we are interested in the url.

 

if { [HTTP::uri] contains ".pt?" } {

 

if { [HTTP::version] eq "1.1" } {

 

if { [HTTP::header is_keepalive] } {

 

HTTP::header replace "Connection" "Keep-Alive"

 

}

 

HTTP::version "1.0"

 

}

 

}

 

}

 

when HTTP_RESPONSE {

 

grab the response

 

if { [HTTP::uri] contains ".pt?" } {

 

if { [HTTP::header exists "Content-Length"] } {

 

set content_length [HTTP::header "Content-Length"]

 

if { $content_length > 399 } {

 

if { $content_length < 601 } {

 

HTTP::collect $content_length

 

}

 

}

 

}

 

}

 

}

 

when HTTP_RESPONSE_DATA {

 

look for Meta Refresh

 

if {[HTTP::payload] contains "meta HTTP-EQUIV=\"REFRESH\" CONTENT=\"0;" }{

 

look for refresh URL

 

set urlresponse [findstr [HTTP::payload] "URL=" 4 {">}]

 

if { $urlresponse != "" } {

 

pull URL out of URL Tag in Meta Refresh statement

 

respond with 302

 

HTTP::respond 302 Location $urlresponse

 

 

}

 

}

 

}

3 Replies

  • Perfect, thanks. I knew there was a reason and that the work around was going to be simple.

     

     

    It is far better to be frustrated as a noob not knowing how to store a variable than to be frustrated as an expert with a memory and CPU pig that caters to noobs. Keep it light and thin!

     

     

    Thanks again,

     

    Scott
  • We found another issue.

     

    The application that we support requires some headers/cookies.

     

     

    Is there any way to add those headers/cookies while we are doing the redirect instead of the refresh tag?

     

     

  • Can you provide more detail on what the application requires and why?

    You can set a cookie in responses using HTTP::respond by adding Set-Cookie "cookie_name=cookie_value\; path=/test\; etc...". You can check the HTTP::respond wiki page (Click here) for details. Here is a quick example which issues a 302 redirect and expires a cookie:

    
         Send a redirect and expire the session cookie
        HTTP::respond 302 Location https://example.com/path/to/file.asp Set-Cookie "$cookie_name=null\;Expires=Thurs, 01-Jan-1970 00:00:00 GMT"

    I don't think you can force a client to include an arbitrary header in a subsequent request based on any data you send in a redirect. You might be able to hack something together using javascript, but I'm not certain it's possible/the exact javascript syntax to do it.. Maybe you could you parse the cookie name/value in HTTP_REQUEST and insert the HTTP header before the request is sent to the app?

    Aaron