Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

HTTP::collect does not function as expected

iRule written below does not collect the specified amount (1024 Bytes) of payload data. Am I missing something here? When I debug the payload contents, the chunked payload size amounts to only about 869 Bytes, while the specified content_length is 1024 Bytes. The size of the actual length is around 2.55 KB, lager than the specified length.

The HTTP::method is POST

BIG-IP LTM 1600

TMOS 12.1.0

when HTTP_REQUEST {
        if { [HTTP::host] contains "test-main" } {
           pool pool_test-main
           return
        } elseif { [HTTP::host] contains "test01" } {
                 pool pool_test01
                 return
        } else {
                pool pool_test02

                if {[HTTP::uri] contains "web_dummy"} {
                    if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= 1024}{
                        set content_length [HTTP::header "Content-Length"]
                    } else {
                        set content_length 1024
                    }

                    # collect					
                    HTTP::collect $content_length	                
                } 
                return
        }
}

when HTTP_REQUEST_DATA {
       log local0. "collected data.....POST Data: [HTTP::payload]"
       foreach x [split [HTTP::payload] "&"] {
       if { $x starts_with "user_ref=" } {
            set user_ref [lindex [split $x "="] 1]
            if { [matchclass $user_ref equals CX_SERVICE_ID] }{
               HTTP::uri [string map {"/web_dummy" "/notify_dummy"} [HTTP::uri]]
               pool pool_test00
               return
               }
           }
       }
    return
}

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi,

I think that your behaviour is correct. let me explain.

When you specify 1024 Bytes, F5 will collects the amount of data that you specify. If the specified amount of data exceeds the amount in the Content-Length response header, only the smaller amount will be collected.

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

So If your request is chunked F5 will collexts only the smaller amount so 869 bytes.

For information, Chunking is a concept introduced in HTTP/1.1 in order to reduce the amount of local storage required on the web server for sending responses.

So in your case if you want to see collect data to 1024 bytes you have to Force the server to HTTP/v1.0 prevents chunking...

# The following example includes collection counter / recollect logic to process payloads > 1MB in size. (Untested, may not be optimal -- please update with improvements.)

when HTTP_REQUEST {
  # Don't allow data to be chunked
  if { [HTTP::version] eq "1.1" } {
    if { [HTTP::header is_keepalive] } {
      HTTP::header replace "Connection" "Keep-Alive"
    }
    HTTP::version "1.0"
  }
  set collected 0
}

https://devcentral.f5.com/questions/request-response-chunking

Keep me update please.

Regards

0
Comments on this Answer
Comment made 5 months ago by rsacheen 176

Thank you for the response and additional info. I appreciate.

I tried HTTP::version "1.0", but it did not fix the problem.

In my case, I am trying to collect request payload not response.

Both of my Content-Length request/response headers are the same (2.5KB)

The specified amount (1024Bytes) does not exceed Content-Length response header (2.5KB) The debug output of $content_length shows 1024 as expected, but the log output of below code gives only around 870Bytes of palyload data.

log local0. "collected data.....POST Data: [HTTP::payload]"

I tried changing the specified content_length to for example 500 or 1500. The collected payload data is almost always the same (870Bytes). It's kind of weird.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Try with any one of below code:

set content_length 1048576 (Example for 1MB)

or

set max_content_length = 524288 (Example for 512KB)

and then call content length in your code.

0
Comments on this Answer
Comment made 5 months ago by rsacheen 176

Thank you for the response. I want to collect 1KB, but the actual collected payload data is only about 870Bytes.
set content_length 1024

0