For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Sriram_129909's avatar
Sriram_129909
Icon for Nimbostratus rankNimbostratus
Nov 07, 2013

iRule to check for a post body

I am trying to look for a post body element using http::payload. I got the following iRule from internet. But the http::collect line is obstructing my page.

 iRule for P2 Project
when HTTP_REQUEST {
    Send the data using local7 facility <190>
    if { not ([HTTP::cookie exists SITESERVER] ) } {
        set F2C "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"
        HTTP::cookie insert name "F2C" value $F2C
    }
    set cookie [HTTP::header cookie]
    HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--[URI::path [HTTP::uri]][URI::basename [HTTP::uri]]--QS=[HTTP::query]--C=[HTTP::header cookie]--UA=[HTTP::header User-Agent]--CT=[HTTP::header "Content-type"]"

    if { [HTTP::uri] contains "landingServlet" and [HTTP::method] eq "POST" } {
        HTTP::collect [HTTP::header value Content-Length]

    }
}

when HTTP_RESPONSE {
    if { [info exists F2C] and $F2C ne ""} {
        HTTP::cookie insert name "F2C" value $F2C
        unset -nocomplain F2C
    }

}

when HTTP_REQUEST_DATA {
    if { [HTTP::uri] starts_with "/airlines/landingServlet" } {
        set refid "unknown"
        set refclickid "unknown"
        foreach x [split [string tolower [HTTP::payload]] "&"] {
                if { $x starts_with "refid=" } {
                        set refid [lindex [split $x "="] 1]
                } 
                 if { $x starts_with "refclickid=" } {
                        set refclickid [lindex [split $x "="] 1]
                }   
        }
    HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--pbrefid=$refid--pbrefclickid=$refclickid--F2C=$F2C"
    }
}

10 Replies

  • A few thoughts:

     

    1. Make sure your request actually has a Content-Length header.

       

    2. How do you know the collect command is causing the problem? Are there any specific LTM log entries?

       

    3. The HTTP_REQUEST_DATA event will only fire when you issue the HTTP::collect command, so you can probably get rid of the URI check in that event.

       

    1. I will
    2. I commented the line that has HTTP::Collect and the page was opening up
    3. I guessed so. Thanks!
  • I commented the line that has HTTP::Collect and the page was opening up

     

    That may also mean the DATA event is failing. Drop some Syslog messages into each of these events and see where it's failing.

     

  • I tried all permutations. If I uncomment HTTP::collect line, the submit on page that ends with /landingServlet fails. And yes, if I look at the iRule statistics, the HTTP_REQUEST_DATA section shows failures.

     

  • Try this version with some additional logging:

    when HTTP_REQUEST {
        Send the data using local7 facility <190>
        if { not ([HTTP::cookie exists SITESERVER] ) } {
            set F2C "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"
            HTTP::cookie insert name "F2C" value $F2C
        }
        set cookie [HTTP::header cookie]
        HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--[URI::path [HTTP::uri]][URI::basename [HTTP::uri]]--QS=[HTTP::query]--C=[HTTP::header cookie]--UA=[HTTP::header User-Agent]--CT=[HTTP::header "Content-type"]"
        if { ( [HTTP::uri] contains "landingServlet" ) and ( [HTTP::method] equals "POST" ) } {
            log local0. "Start collecting: [HTTP::header Content-Length]"
            HTTP::collect [HTTP::header Content-Length]
        }
    }
    when HTTP_RESPONSE {
        if { [info exists F2C] and $F2C ne ""} {
            HTTP::cookie insert name "F2C" value $F2C
            unset -nocomplain F2C
        }
    }
    when HTTP_REQUEST_DATA {
        log local0. "Entering Request Data event"
        set refid "unknown"
        set refclickid "unknown"
        foreach x [split [string tolower [HTTP::payload]] "&"] {
            log local0. "x = $x"
            if { $x starts_with "refid=" } {
                set refid [lindex [split $x "="] 1]
                log local0. "refid = $refid"
            } 
            if { $x starts_with "refclickid=" } {
                set refclickid [lindex [split $x "="] 1]
                log local0. "refclickid = $refclickid"
            }   
        }
        HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--pbrefid=$refid--pbrefclickid=$refclickid--F2C=$F2C"
    }
    
  • Thank you very much for working on my iRule. However I have apparently figured out another way - meaning reading off of the payload in the HTTP_REQUEST itself. The following is the iRule. This works out well for me.

    when HTTP_REQUEST {
        Send the data using local7 facility <190>
        if { not ([HTTP::cookie exists SITESERVER] ) } {
            set F2C "[string range [AES::key 128] 15 end][string range [AES::key 128] 15 end]"
            HTTP::cookie insert name "F2C" value $F2C
        }
        set cookie [HTTP::header cookie]
        HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--NW--80--P2--[URI::path [HTTP::uri]][URI::basename [HTTP::uri]]--QS=[HTTP::query]--C=[HTTP::header cookie]--UA=[HTTP::header User-Agent]--CT=[HTTP::header "Content-type"]"
    
        if { [HTTP::uri] starts_with "/airlines/landingServlet" and [HTTP::method] eq "POST" } {
            set payload [HTTP::payload]
            set refid "unknown"
            set refclickid "unknown"
            foreach x [split [string tolower $payload] "&"] {
                if { $x starts_with "refid=" } {
                    set refid [lindex [split $x "="] 1]
                } 
                if { $x starts_with "refclickid=" } {
                    set refclickid [lindex [split $x "="] 1]
                }   
            }
            HSL::send [HSL::open -proto UDP -pool syslog_server_pool_1] "<190> [IP::client_addr] \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] --[IP::local_addr]--NW--80--P2--pbrefid=$refid--pbrefclickid=$refclickid--C=[HTTP::header cookie]"
            unset payload
        }
    }
    
    when HTTP_RESPONSE { 
        if { [info exists F2C] and $F2C ne ""} {
            HTTP::cookie insert name "F2C" value $F2C
            HTTP::cookie expires F2C 630720000
            unset -nocomplain F2C
        }
    
    }
    
  • Good news. Just be aware that you're able to do this because the entire request fits inside a single TCP packet. If for whatever reason the client sends a larger packet (ie. more headers and/or larger payload data), you may find this option will miss some of the data. The HTTP::collect and subsequent HTTP_REQUEST_DATA event will buffer the request payload across TCP packets.

     

  • Oh, that's a good catch. May I know what is the limit of payload data after which it splits it across multiple requests?