Forum Discussion
irule: reading HTTP body in POST
There are several ways to do this. The samples below are just two abstracts for evaluating the payload of a request (and/or response).
HTTP::collect method
when HTTP_REQUEST {
if { [HTTP::method] eq "POST" } {
Trigger the collection for up to 1MB of data
if { [HTTP::header Content-Length] ne "" and [HTTP::header value Content-Length] <= 1048576 } {
set content_length [HTTP::header value 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_REQUEST_DATA {
Do stuff with the payload
set payload [HTTP::payload]
log local0. $payload
}
In this example you're going to collect the request payload if the request method is a POST. The good thing about this method is that you can evaluate the entire payload. The bad thing is that this method can consume a lot of processing if the payloads are large. Notice in the HTTP_REQUEST event that the payload length has been limited to 1mb. If the values that you're looking for are beyond that, then you have to increase this value at the possible expense of processing cycles. Once inside the HTTP_REQUEST_DATA event, the payload of the request is available via HTTP::payload. There are also instances where the payload may traverse multiple requests, because of the size of the request. This isn't too common, but if it happens you'll need to issue additional HTTP::collect events INSIDE the HTTP_REQUEST_DATA event.
STREAM method
==========================
when HTTP_REQUEST {
STREAM::disable
if { [HTTP::method] equals "POST" } {
STREAM::expression "@user=\[^&\]+?@@ @password=\[^&\]+?@@"
STREAM::enable
}
}
when STREAM_MATCHED {
log local0. [STREAM::match]
STREAM::replace [STREAM::match]
}
==========================
In this method you're using a generic STREAM profile to filter on specific values within the payload (also if it's a POST request). The benefit of this approach is that it's VERY fast and not constrained by the size of the payload. The down side is that you have to be very explicit about what you're looking for. In the above example I've defined an explicit STREAM expression: "@user=\[^&\]+?@@ @password=\[^&\]+?@@" that is looking for two values. Essentially it says, anything that starts with "user=" or "password=" and terminates with an ampersand (&) character. If the STREAM profile sees either of these it'll fire the STREAM_MATCHED event and expose the match in STREAM::match. From that point you can replace or remove the content, terminate the connection, or whatever else you need.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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