Forum Discussion

Val_Boudreau_11's avatar
Val_Boudreau_11
Icon for Nimbostratus rankNimbostratus
Jun 29, 2005

Emulating Stream using iRules

Hello,

 

 

I am new to BIG-IPs (v9.1) and the writing of iRules.

 

 

Looking for some assistance on emulating multiple ‘Stream” profiles using a single iRule.

 

 

In short, if I could apply the two “Stream” profiles below to my virtual server, I would be all set, but since only one stream profile can be applied to a virtual server, I need a way to do this string replacement via iRules. I did originally have a stream profile with a Source = http and a Target = https, and this resolved our basic issue, but the stream profile is too vague and is causing other issues with the application we are working with.

 

 

Stream Profile 1

 

Source: http://myhost.company.com

 

Target: https://myhost.company.com

 

 

Stream Profile 2

 

Source: http%

 

Target: https%

 

 

I discussed this issue with F5 support, and they provided the following information: “You will need to define a class with "http://myhost.compnay.com" and "http%" in it. You will want to use a rule that says when HTTP_REQUEST do this and then we do an if statement using matchclass that looks for the classes we are trying to match and based on that uses the HTTP::REDIRECT statement to redirect you to the desired URL. Take this concept to devcentral.f5.com and they should be able to point you in the right direction for a sample rule.”

 

 

I created a string class (Data Group List) as follows:

 

 

Name: http_calls

 

Type: String

 

String Records: "http%, "http://myhost.company.com

 

 

Any help on how I could emulate a stream via iRule would be greatly appreciated.

 

 

Thanks in Advance!

1 Reply

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Because the way HTTP works with regard to Content-Length, you will need to buffer the entire payload, replace the strings and then release the payload.

    The reason for this is that as the payload size increases due to the replacements, the HTTP Content-Length header needs to be increased. But because the header is at the beginning and you don't know how many times you are going to substitute, you can't do anything until you have the entire payload.

    However, the potential problem with buffering the entire payload, is that as the size and number of responses go up, the memory usage and concurrency are affected. So, as long as the responses which you are searching & replacing are not too large this should work fine.

    Click here for the article which provides an example of how to buffer the response and then modify it:

    http://devcentral.f5.com/Default.aspx?TabID=29&newsType=ArticleView&articleId=25

    Here is another similar example which uses "string map" instead. String map is slightly more efficient than regsub and has the advantage that it can search & replace multiple key value pairs in one pass:

     
     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% https% \ 
              http://myhost.company.com https://myhost.company.com \ 
           } $payload] 
        if { $new_payload ne $payload } { 
            Replace the content if there was any matches 
           HTTP::payload replace 0 $length $new_payload 
        } 
     }