Forum Discussion

seungho_33263's avatar
seungho_33263
Icon for Nimbostratus rankNimbostratus
Mar 14, 2012

Delayed response occured when I changed HTTP response data.

I want to replace http link to https link in html body content.

 

When I tested below code in the test environment, it worked correctly.(only IE test)

 

 

but it didn't work customer's environment.

 

(IE opened the page in 20sec, Chrome and Firefox didn't open)

 

The difference is response data's size.

 

 

In the test environment, the response data size are about 200Bytes, but the customer's response data size are over 32KB.

 

 

I think one of the reason is that it takes much time to replace after searching string pattern.

 

 

Do you have any advice for solving this problem?

 

 

 

-below-

 

 

when HTTP_RESPONSE {

 

HTTP::collect 30000

 

}

 

when HTTP_RESPONSE_DATA {

 

if {[HTTP::header "Content-Language"] contains "en-US"}{

 

set object [HTTP::payload]

 

regsub "http://ab.cde.co.kr/webapps/login/" $object "https://ab.cde.co.kr/webapps/login/" newdata

 

log "BB REDIRECT TEST(len [HTTP::payload length])"

 

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

 

HTTP::release

 

}

 

}

 

 

=or==============================================================

 

when HTTP_RESPONSE {

 

if {[HTTP::header "Content-Language"] contains "en-US"}{

 

HTTP::collect 33000

 

}

 

}

 

 

when HTTP_RESPONSE_DATA {

 

if {[HTTP::header "Content-Language"] contains "en-US"}{

 

set object [HTTP::payload]

 

set _org "http://ab.cde.co.kr/webapps/login/"

 

set _new "https://ab.cde.co.kr/webapps/login/"

 

set offset [string first "http://ab.cde.co.kr/webapps/login/" $object 0]

 

if { $offset > 0 } {

 

set len [string length $_org]

 

set last [expr {$offset + $len}]

 

set _newobject [string replace $object $offset $last $_new]

 

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

 

HTTP::release

 

}

 

}

 

}

 

 

  • Hi seungho,

     

     

    Using a stream profile and STREAM::expression based iRule should be faster and more efficient as you're not having TMM buffer the full payload. See the STREAM::expression wiki page for some examples:

     

     

    https://devcentral.f5.com/wiki/iRules.stream__expression.ashx

     

     

     

    If for some reason you choose to continue using HTTP::collect, make sure to only collect response payloads if they're ones you want to rewrite (based on content-type starting with text and your content-language being en-US). There's no reason to collect other responses which you aren't going to rewrite.

     

     

    Aaron
  • Thanks for your advice.

     

     

    I figured out the reason why the response delayed. It was this code, "HTTP::collect 33000."

     

    HTTP_RESPONSE_DATA event called when received data reached 33000 bytes or TIME_OUT.

     

    I reduced the collect size to 30000. so, the delayed problem was temporally solved.

     

    But it still works in only IE browser.

     

    In Chrome, Firefox, Opera browser environment, it doesn't work.

     

     

    According to my test,

     

    when there is no change in the response data Chrome works,

     

    when there is change in the response data Chrome doesn't work.

     

     

    Do you know the reason?

     

     

    --CUR SOURCE--------------------------------------------------------------------------------------------------------------------

     

    when HTTP_RESPONSE {

     

    HTTP::collect 30000

     

    }

     

     

    when HTTP_RESPONSE_DATA {

     

    set object [HTTP::payload]

     

    set _org "http://ab.cde.ac.kr/webapps/login/"

     

    set _new "https://ab.cde.ac.kr/webapps/login/"

     

     

    set offset [string first $_org $object 0]

     

    if { $offset > 0 } {

     

    set len [string length $_org]

     

    set last [expr {$offset + $len}]

     

    set newobject [string replace $object $offset $last $_new]

     

     

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

     

    }

     

    HTTP::release

     

    }

     

  • ykkim's avatar
    ykkim
    Icon for Nimbostratus rankNimbostratus
    Hi Aron

     

    Thanks for your answer. I'm working with Seungho. I'm updating our status and questions.

     

     

    As Seungho wrote already, source was like "SOURCE1".

     

    Then,

     

    case1. An expected(well changed) response page was displayed on MS-IE soon.

     

    -- In all the tests, every response was HTTP 1.0.

     

    case2. Nothing appeared on Chrome. At that time, Wireshark captured the full of page contents which I expected.

     

    -- Response was HTTP 1.1.

     

    case3. If the collection length was less than 27000(not exact number), even Chrome showed perfect page like MS-IE. Captured packets were same whith case 2.

     

    -- Response was HTTP 1.1.

     

     

    [Question1] Can collect length affect HTTP response phase?

     

     

    Based on case2 and case3, I thought, it doesn't matter whether HTTP1.0 or HTTP1.1. Nevertheless, I put several lines changing HTTP request version from 1.1 to 1.0 like SOURCE2.

     

    Then,

     

    case4. It worked well on MS-IE. Response was HTTP 1.0, same with case1.

     

    case5. It worked well on Chromel, too. Even though actual collected response was more than 32000 bytes, no problem. Response was HTTP1.0. (Some decorations in response part were added far later. They didn't exist during case5 tests.)

     

     

    [Question2]

     

    What does HTTP version have to do with the operation of iRule(HTTP::collect, precisely)? Can you explain the relationship between them?

     

     

    [Question3]

     

    (This is an extra.) MS-IE client sends HTTP1.1 request. And yet, how come server(or F5) responses in HTTP 1.0 automatically, with no "1.0 pushing" routine.

     

     

     

    ------ SOURCE 1 ----------------------------------------------

     

    when HTTP_RESPONSE {

     

    HTTP::collect 30000

     

    }

     

     

    when HTTP_RESPONSE_DATA {

     

    set object [HTTP::payload]

     

    set _org "http://ab.cde.ac.kr/webapps/login/"

     

    set _new "https://ab.cde.ac.kr/webapps/login/"

     

     

    set offset [string first $_org $object 0]

     

    if { $offset > 0 } {

     

    set len [string length $_org]

     

    set last [expr {$offset + $len}]

     

    set newobject [string replace $object $offset $last $_new]

     

     

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

     

    }

     

    HTTP::release

     

    }

     

     

     

     

    ------ SOURCE 2 ----------------------------------------------

     

    when HTTP_REQUEST {

     

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

     

    if { [HTTP::header is_keepalive] } {

     

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

     

    }

     

    HTTP::version "1.0"

     

    }

     

    }

     

     

    when HTTP_RESPONSE {

     

    if {[HTTP::header "Content-Type"] contains "text" && [HTTP::header "Content-Language"] contains "en-US"} {

     

    if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576 } {

     

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

     

    }

     

    else {

     

    set col_len 1048576

     

    }

     

    HTTP::collect $col_len

     

    }

     

    }

     

     

    when HTTP_RESPONSE_DATA {

     

    set object [HTTP::payload]

     

    set _org "http://ab.cde.ac.kr/webapps/login/"

     

    set _new "https://ab.cde.ac.kr/webapps/login/"

     

     

    set offset [string first $_org $object 0]

     

    if { $offset > 0 } {

     

    set len [string length $_org]

     

    set last [expr {$offset + $len}]

     

    set newobject [string replace $object $offset $last $_new]

     

     

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

     

    }

     

    HTTP::release

     

    }