Forum Discussion

Andrew_Bretten_'s avatar
Andrew_Bretten_
Icon for Nimbostratus rankNimbostratus
Oct 29, 2006

payload replace fails against content from .jsp ?

I have the following iRule appled to a virtual server

 

 

when HTTP_RESPONSE_DATA {

 

set find "http://"

 

set replace "https://"

 

set payload [HTTP::payload]

 

if {[regsub -all $find $payload $replace new_response] > 0} {

 

HTTP::payload replace 0 [HTTP::payload length] $new_response

 

}

 

}

 

 

If I throw up a simple .html page like

 

 

 

 

 

 

 

 

The Link is re-written to https correctly.

 

 

However the real application we are trying to "fix" is returning

5 Replies

  • If you want to replace http with https in the HTTP content, try using the stream profile. It's simpler and should be much faster than using regsub and HTTP::payload.

     

     

    Try searching the forum for stream to find a few detailed posts on using the stream profile.

     

     

    Aaron
  • aaron, thanks for the reply.

     

     

    I had already discovered I could use a stream profile instead but had only used the basic function that would rewrite all http:// instances.

     

     

    I wanted to have the capability to be more granular (eventually).

     

     

    Then after posting this I trolled and found that 9.2 supports multiple source/targets in a stream profile.

     

     

    So I have tested a stream profile which works fine (as you suggested).

     

     

    So my posting on iRules is more me wanting to figure out the iRule just because its bugging me why its not working. I'm leaving the production app on the stream profile.

     

     

    I've got an open case with F5 and reported my findings today as an update to that case...I think the regusb in the iRule is having a problem with something in the html output......since the iRule works fine against a more basic web page with the same http:// links.

     

     

    One thing I'm looking at is the web apps plugin is putting about 20 carriage returns very near the top of the html, perhaps that's throwing regsub off. Or maybe the header is reporting the wrong content length.....anyway I figured I'd give the html code to F5 along with my iRule and see if they would take a look.

     

     

    I'm a little wary about posting the code to a public forum, I might have to get permission from my own company to do that.
  • Ok I've made more progress.....regsub seems to be operating against only a certain amount of data.

     

     

    If I put a link closer to the start of the HTTP payload....it gets rewritten.

     

     

    Consider the following http code....the iRule fails to rewrite the link....take out a few of the comment lines...the iRule succeeds in rewriting the link.

     

     

    Andy

     

     

     

     

     

     

     

    test

     

     

     

     

  • Hi Andy,

     

     

    It looks like you found a solution. Can you let us know what you figured out?

     

     

    Thanks,

     

    Aaron
  • Ok....here's what I ended up with. From another thread, I found I can multiple match/replaces in a stream profile.

     

     

    Simply, create a stream profile, leave source empty....put this in destination.

     

    searchreplacesearch replacesearchreplace

     

    The seperator () can be anything, whatever the first character is, is assumed to be the seperator.

     

     

    This is much faster and simlier than trying to force an iRule to parse the entire HTTP response.

     

     

    I did however also found a good link on how to load the complete HTTP response, which was the first problem I had with my iRule.

     

    However, even after fixing that....the iRule still does not rewrite every single http:// link in the document, and I'm sick of debugging it.....The stream profile works great.

     

     

    Here's the iRule I ended up with (but by no means 100% working).

     

     

    when HTTP_REQUEST {

     

    Don't allow data to be chunked.

     

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

     

    if {[HTTP::header is_keepalive]} {

     

    Adjust the Connection header.

     

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

     

    }

     

    HTTP::version "1.0"

     

    }

     

    }

     

    when HTTP_RESPONSE {

     

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

     

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

     

    } else {

     

    set content_len 4294967295

     

    }

     

    if { $content_len > 0 } {

     

    HTTP::collect $content_len

     

    }

     

    }

     

    when HTTP_RESPONSE_DATA {

     

    set payload [HTTP::payload]

     

    set length [HTTP::payload length]

     

    set new_payload [string map {http://tp https://tp} $payload]

     

    if { $new_payload ne $payload } {

     

    Replace the content if there was any matches

     

    HTTP::payload replace 0 $length $new_payload

     

    }

     

    }

     

     

    Andy