Forum Discussion
Chadri_103513
Nimbostratus
Sep 01, 2009ot Payload data npassing with POST inspection
Hi,
I need some help with an iRule that is designed to inspect both GET and POST data, compare it against a data-group of accepted commands, and then redirect it to the appropriate pool. The GET portion of this iRule is working, however, I am having issues with the POST portion. While debugging the iRule, I see that the POST portion is inspecting the traffic, matching the data-group, and rewriting the header but the payload doesn't appear to be making it back to the server. How do I make sure that all payload data is making it back to the server?
when HTTP_REQUEST {
set exampleHost "example.staging.local"
set examplePath "/exampleproxy/exampleproxy.aspx"
set examplePool "example.staging-80"
HTTP::header insert "OLD_HOST" [HTTP::host]
if { [HTTP::version] eq "1.1" } {
if { [HTTP::header is_keepalive] } {
HTTP::header replace "Connection" "Keep-Alive"
}
HTTP::version "1.0"
}
if { [HTTP::host] eq $exampleHost } {
pool $examplePool
return
}
elseif { [string tolower [HTTP::path]] eq "$examplePath"} {
HTTP::header replace "Host" $exampleHost
pool $examplePool
return
}
if { [HTTP::method] eq "GET"} {
set cmd [ URI::query [string tolower [HTTP::uri]] command ];
if { [matchclass $::example_staging equals $cmd] } {
HTTP::header replace "Host" $exampleHost
HTTP::path $examplePath
pool $examplePool
return
}
}
elseif { [HTTP::method] eq "POST" } {
if { [HTTP::header exists "Content-Length"] } {
HTTP::collect [HTTP::header Content-Length]
} else {
HTTP::collect 256
}
}
}
when HTTP_REQUEST_DATA {
set cmd [string tolower [getfield [lsearch -inline [split [HTTP::payload] "&"] command=*] = 2]]
if {[matchclass $::example_staging equals $cmd]} {
HTTP::header replace "Host" $exampleHost
HTTP::path $examplePath
set payload [HTTP::payload]
pool $examplePool
return
}
}
Any help would be greatly appreciated.
Thanks.
3 Replies
- Nat_Thirasuttakorn
Employee
maybe HTTP::release can help
(put it before return inside HTTP_REQUEST_DATA. actually, you don't need return command there)
Nat - hoolio
Cirrostratus
Hi,
I'd be suspicious about the default of collecting 256 bytes for POST requests without a Content-Length header. Can you add logging to that portion of the rule:... elseif { [HTTP::method] eq "POST" } { log local0. "[IP::client_addr]:[TCP::client_port]: POST request to [HTTP::host][HTTP::uri]\ with Content-Length: [HTTP::header Content-Length]" if { [HTTP::header exists "Content-Length"] } { HTTP::collect [HTTP::header Content-Length] log local0. "[IP::client_addr]:[TCP::client_port]: Collecting [HTTP::header Content-Length] bytes" } else { HTTP::collect 256 log local0. "[IP::client_addr]:[TCP::client_port]: No Content-Length, collecting 256 bytes: Req: [HTTP::request]" } } when HTTP_REQUEST_DATA { log local0. "[IP::client_addr]:[TCP::client_port]: Collected [HTTP::payload length] bytes: [HTTP::payload]" Parse the command from the request payload set cmd [string tolower [getfield [lsearch -inline [split [HTTP::payload] "&"] command=*] = 2]] set cmd [string tolower [URI::query "?[HTTP::payload]" command]] if {[matchclass $::example_staging equals $cmd]} { log local0. "[IP::client_addr]:[TCP::client_port]: Matched $cmd, replacing host header, path and setting pool." HTTP::header replace "Host" $exampleHost HTTP::path $examplePath pool $examplePool } }
Assuming you're parsing parameter names and values that are URL encoded in the format param1=value1¶m2=value2, you could replace this line:
set cmd [string tolower [getfield [lsearch -inline [split [HTTP::payload] "&"] command=*] = 2]]
with this line:
set cmd [string tolower [URI::query "?[HTTP::payload]" command]]
I would guess the inbuilt processing of the parameters would be faster than the list commands.
Aaron - hoolio
Cirrostratus
Hi Nat,
The wiki page for HTTP::release says:
http://devcentral.f5.com/wiki/default.aspx/iRules/http__release
Releases the data collected via HTTP::collect. Unless a subsequent HTTP::collect command was issued, there is no need to use the HTTP::release command inside of the HTTP_REQUEST_DATA and HTTP_RESPONSE_DATA events, since (in these cases) the data is implicitly released.
Do you think it still might be required? I was thinking the issue might be an atypical client sending a chunked request. In that case, the request wouldn't have a Content-Length header and could be hitting the HTTP::collect 256 statement.
This seems like an odd problem, as the payload isn't being modified in any way...
Thanks,
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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