Forum Discussion

Marek_George's avatar
Marek_George
Icon for Nimbostratus rankNimbostratus
Jul 23, 2010

prefix based pool selection with content rewriting

Hi,

 

I use one virtual server and several backend systems (pools). The requested uri contains a prefix,

 

that me allow to set the right pool when the request was send to bigip. For further requests I must

 

rewrite the content from the specific backend system and insert the prefix.

 

 

Something going wrong!

 

Requests and responses are not rewritten correctly. The bigip mixed requests and responses.

 

 

Example: Requested was "/GSRV-SRV1" and the response was processed for "/GSRV-SRV2".

 

 

Where is the problem?

 

 

Version: BIG-IP 9.3.1 Build 81.1

 

 

 

when HTTP_REQUEST {

 

set SRVResponse ""

 

switch -glob [string toupper [HTTP::uri]] {

 

"/GSRV-SRV1*" {

 

discard the prefix

 

HTTP::uri [string range [HTTP::uri] 10 end]

 

set SRVResponse "/GSRV-SRV1"

 

pool myServer1

 

}

 

"/GSRV-SRV2*" {

 

HTTP::uri [string range [HTTP::uri] 10 end]

 

set SRVResponse "/GSRV-SRV2"

 

pool myServer2

 

}

 

"/GSRV-SRV3*" {

 

HTTP::uri [string range [HTTP::uri] 10 end]

 

set SRVResponse "/GSRV-SRV3"

 

pool myServer3

 

}

 

}

 

}

 

 

when HTTP_RESPONSE {

 

catch the content

 

set content_length 0

 

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

 

else { set content_length 2000000 }

 

 

if { $content_length > 0 } { HTTP::collect $content_length }

 

}

 

 

when HTTP_RESPONSE_DATA {

 

switch $SRVResponse {

 

"/GSRV-SRV1" {

 

do something like rewriting

 

}

 

"/GSRV-SRV2" {

 

do something like rewriting

 

}

 

"/GSRV-SRV3" {

 

do something like rewriting

 

}

 

}

 

}

2 Replies

  • Hamish's avatar
    Hamish
    Icon for Cirrocumulus rankCirrocumulus
    Without looking too closely, I'd suggest you put some logs in your code while developing so you can tell what it's doing and why...

     

     

     

    H
  • Hi Marek,

    As Hamish suggested, you should be able to add debug logging to the iRule to figure out what's happening and why. When the third response isn't rewritten to the server1 condition, do you see the prior request being parsed as server1?

    Also, it would be more efficient to use a blank stream profile and STREAM::expression based iRule to rewrite the response content compared with having LTM buffer the response payload. You can check the STREAM::expression wiki page for details and examples: http://devcentral.f5.com/wiki/default.aspx/iRules/stream__expression

    If you do stick with the HTTP::collect version of the iRule, I'd suggest you limit the payload collection to a maximum of 2Mb regardless of what the server Content-Length header is set to. If TMM collects more than 4Mb of payload it will crash:

    SOL6578: TMM will crash if an iRule collects more than 4MB of data

    https://support.f5.com/kb/en-us/solutions/public/6000/500/sol6578.html

    The creditcard scrubber Codeshare example demonstrates a good way to limit payload collection to 4Mb:

    
    when HTTP_RESPONSE {
    
       Only check responses that are a text content type (text/html, text/xml, text/plain, etc).
      if { [HTTP::header "Content-Type"] starts_with "text/" } {
    
         Get the content length so we can collect the data (to be processed in the HTTP_RESPONSE_DATA event)
         Limit collection to 1Mb (1048576 minus a little to spare) - See SOL6578 for details
        if { [HTTP::header exists "Content-Length"] } {
          if { [HTTP::header "Content-Length"] > 1048000 }{
             Content-Length over 1Mb so collect 1Mb
            set content_length 1048000
          } else {
             Content-Length under 1Mb so collect actual length
            set content_length [HTTP::header "Content-Length"]
          }
        } else {
           Response did not have Content-Length header, so use default of 1Mb
          set content_length 1048000
        }
         Don't collect content if Content-Length header value was 0
        if { $content_length > 0 } {
           HTTP::collect $content_length
        }
      }
    }
     ...
    

    Aaron