Forum Discussion
GavinW_29074
Apr 12, 2012Nimbostratus
Check HTTP Response Data for string
Hi there,
We've got an intermittent issue with one of our applications which I'm trying to get to understand a bit better using our F5's and iRules...
Basically, sometimes the application fails to include the head block in the HTML responses.
I want to be able to use an iRule to log every time this happens?
What I'm trying to get is the most economical and reliable way of searching the response data for the given string.
Is this something that can be achieved using STREAM profiles?
Comments welcome...
Cheers
Gav
- GavinW_29074NimbostratusHi there,
Source Control: Where: $HeadURL: http://subversion.card.co.uk/svn/products/Utilities/F5/iRules/++Common++SplunkHTTP.txt $ Last Modified On: $Date: 2012-02-16 12:27:33 +0000 (Thu, 16 Feb 2012) $ Last Modified By: $Author: gavinw $ Revision: $Revision: 57745 $ when RULE_INIT { set static::LogInvalidRespDebug 1 } when HTTP_REQUEST priority 100 { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processin HTTP Request at Priority 100..." } if { [HTTP::header exists "X-Requested-With"] } { if {$static::LogInvalidRespDebug > 0} { log local0.info "X-Requested-With HTTP Header Present. Must be AJAX Request." } return } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non AJAX Request. Processing further." } Only looking for HTML Requests if { [HTTP::header "Accept"] contains "text/html" } { if {$static::LogInvalidRespDebug > 0} { log local0.info "Accept Header contains 'text/html'. Recording." } Prevent the server from sending a compressed response remove the compression offerings from the client HTTP::header remove "Accept-Encoding" Don't allow response data to be chunked if { [HTTP::version] eq "1.1" } { Force downgrade to HTTP 1.0, but still allow keep-alive connections. Since HTTP 1.1 is keep-alive by default, and 1.0 isn't, we need make sure the headers reflect the keep-alive status. Check if this is a keep alive connection if { [HTTP::header is_keepalive] } { Replace the connection header value with "Keep-Alive" HTTP::header replace "Connection" "Keep-Alive" } Set server side request version to 1.0 This forces the server to respond without chunking HTTP::version "1.0" } if {$static::LogInvalidRespDebug > 0} { log local0.info "Storing HTTP::request value" } set req_data [HTTP::request] if {$static::LogInvalidRespDebug > 0} { log local0.info "\$req_data = $req_data" } } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non HTML request. Returning. " } return } } } when HTTP_RESPONSE { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing HTTP Response." } Disable the stream filter by default STREAM::disable Check if response type is text if {[HTTP::header value Content-Type] contains "text/html"}{ if {$static::LogInvalidRespDebug > 0} { log local0.info "HTTP Response Content-Type header contains 'text/html'" } set lir_stream_find "ACT" set lir_stream_replace "toe" set lir_stream_expr "@$lir_stream_find@$lir_stream_replace$lir_stream_find@" set lir_stream_expr_cmd "STREAM::expression \{\"$lir_stream_expr\"\}" set lir_stream_enbl_cmd "STREAM::enable" if { $static::LogInvalidRespDebug > 0 } { log local0. "\$lir_stream_expr_cmd: $lir_stream_expr_cmd, \$lir_stream_enbl_cmd: $lir_stream_enbl_cmd" } Execute the STREAM::expression command. Use catch to handle any errors. Save the result to $result if { [catch {eval $lir_stream_expr_cmd} lir_result] } { There was an error trying to set the stream expression. log local0. "Error setting stream expression ($lir_result). Stream profile not set." } else { No error setting the stream expression, so try to enable the stream filter Execute the STREAM::enable command. Use catch to handle any errors. Save the result to $result if { [catch {eval $lir_stream_enbl_cmd} result] } { There was an error trying to enable the stream filter. log local0. "Error enabling stream filter ($lir_result): $lir_result" } else { if { $static::LogInvalidRespDebug > 0 } { log local0. "Successfully configured and enabled stream filter" } } } Trigger collection for up to 1MB of data if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } Check if $content_length is not set to 0 if { $content_length > 0} { HTTP::collect $content_length } } } when HTTP_RESPONSE_DATA { do stuff with the payload set payload [HTTP::payload] } when STREAM_MATCHED { if {$static::LogInvalidRespDebug > 0} { log local0.info "Stream_Matched event triggered" } log local0. "[IP::client_addr]:[TCP::local_port]: matched: [STREAM::match].]" STREAM::replace "[string map {http:// https://} [STREAM::match]]" }
- hooleylistCirrostratusHi Gavin,
- GavinW_29074NimbostratusAaron
when RULE_INIT { set static::LogInvalidRespDebug 1 } when HTTP_REQUEST priority 100 { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processin HTTP Request at Priority 100..." } Bypass by default set bypass 1 if { [HTTP::header exists "X-Requested-With"] } { if {$static::LogInvalidRespDebug > 0} { log local0.info "X-Requested-With HTTP Header Present. Must be AJAX Request." } return } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non AJAX Request. Processing further." } Only looking for HTML Requests if { [HTTP::header "Accept"] contains "text/html" } { if {$static::LogInvalidRespDebug > 0} { log local0.info "Accept Header contains 'text/html'. Recording." } Prevent the server from sending a compressed response remove the compression offerings from the client HTTP::header remove "Accept-Encoding" Don't allow response data to be chunked if { [HTTP::version] eq "1.1" } { Force downgrade to HTTP 1.0, but still allow keep-alive connections. Since HTTP 1.1 is keep-alive by default, and 1.0 isn't, we need make sure the headers reflect the keep-alive status. Check if this is a keep alive connection if { [HTTP::header is_keepalive] } { Replace the connection header value with "Keep-Alive" HTTP::header replace "Connection" "Keep-Alive" } Set server side request version to 1.0 This forces the server to respond without chunking HTTP::version "1.0" } if {$static::LogInvalidRespDebug > 0} { log local0.info "Storing HTTP::request value" } set req_data [HTTP::request] if {$static::LogInvalidRespDebug > 0} { log local0.info "\$req_data = $req_data" } Need to check the repsonse on this one. set bypass 0 } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non HTML request. Returning. " } return } } } when HTTP_RESPONSE { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing HTTP Response." } if { $bypass } { if {$static::LogInvalidRespDebug > 0} { log local0.info "Bypassing this response" } return } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing this response" } Trigger collection for up to 1MB of data if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } Check if $content_length is not set to 0 if { $content_length > 0} { HTTP::collect $content_length } Log output. set ir_hsl [HSL::open -proto UDP -pool splunk_ir] HSL::send $ir_hsl "<190>|Checking HTTP Response Data\n" } } when HTTP_RESPONSE_DATA { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing HTTP Response data." } if { $bypass } { return } else { do stuff with the payload set payload [HTTP::payload] if { $payload contains "" } { if {$static::LogInvalidRespDebug > 0} { log local0. "Payload contains tag." } } else { log local0.crit "Payload doesnt contain tag." HSL::send $ir_hsl "<190>|$clientip requested $uri. Invalid response returned. Request data was: $req_data\n" } } }
- hooleylistCirrostratusYou could add a check to see if the uncollected payload contains and not bother collecting in that case. Also, you can do a case insensitive comparison to match , , etc:
when RULE_INIT { set static::LogInvalidRespDebug 1 } when HTTP_REQUEST priority 100 { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processin HTTP Request at Priority 100..." } Bypass by default set bypass 1 if { [HTTP::header exists "X-Requested-With"] } { if {$static::LogInvalidRespDebug > 0} { log local0.info "X-Requested-With HTTP Header Present. Must be AJAX Request." } return } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non AJAX Request. Processing further." } Only looking for HTML Requests if { [HTTP::header "Accept"] contains "text/html" } { if {$static::LogInvalidRespDebug > 0} { log local0.info "Accept Header contains 'text/html'. Recording." } Prevent the server from sending a compressed response remove the compression offerings from the client HTTP::header remove "Accept-Encoding" Don't allow response data to be chunked if { [HTTP::version] eq "1.1" } { Force downgrade to HTTP 1.0, but still allow keep-alive connections. Since HTTP 1.1 is keep-alive by default, and 1.0 isn't, we need make sure the headers reflect the keep-alive status. Check if this is a keep alive connection if { [HTTP::header is_keepalive] } { Replace the connection header value with "Keep-Alive" HTTP::header replace "Connection" "Keep-Alive" } Set server side request version to 1.0 This forces the server to respond without chunking HTTP::version "1.0" } if {$static::LogInvalidRespDebug > 0} { log local0.info "Storing HTTP::request value" } set req_data [HTTP::request] if {$static::LogInvalidRespDebug > 0} { log local0.info "\$req_data = $req_data" } Need to check the repsonse on this one. set bypass 0 } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Non HTML request. Returning. " } return } } } when HTTP_RESPONSE { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing HTTP Response." } if { $bypass } { if {$static::LogInvalidRespDebug > 0} { log local0.info "Bypassing this response" } return } elseif { [string match -nocase "**" [HTTP::payload]] } { `if {$static::LogInvalidRespDebug > 0} { log local0. "Uncollected payload contains tag." } return } else { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing this response" } Trigger collection for up to 1MB of data if {[HTTP::header exists "Content-Length"] and [HTTP::header "Content-Length"] <= 1048576}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } Check if $content_length is not set to 0 if { $content_length > 0} { HTTP::collect $content_length } Log output. set ir_hsl [HSL::open -proto UDP -pool splunk_ir] HSL::send $ir_hsl "<190>|Checking HTTP Response Data\n" } } when HTTP_RESPONSE_DATA { if {$static::LogInvalidRespDebug > 0} { log local0.info "Processing HTTP Response data." } if { $bypass } { return } else { do stuff with the payload set payload [HTTP::payload] if { [string match -nocase "**" [HTTP::payload]] } { if {$static::LogInvalidRespDebug > 0} { log local0. "Payload contains tag." } } else { log local0.crit "Payload doesnt contain tag." HSL::send $ir_hsl "<190>|$clientip requested $uri. Invalid response returned. Request data was: $req_data\n" } } }
- GavinW_29074NimbostratusAh, that looks a bit easier...
Recent Discussions
Related Content
Â
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects