Forum Discussion

rsacheen's avatar
rsacheen
Icon for Nimbostratus rankNimbostratus
May 16, 2018

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
}

5 Replies

  • 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

  • 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.

     

    • rsacheen's avatar
      rsacheen
      Icon for Nimbostratus rankNimbostratus

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

       

      set content_length 1024

       

  • 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.

     

    • rsacheen's avatar
      rsacheen
      Icon for Nimbostratus rankNimbostratus

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

       

      set content_length 1024