Forum Discussion

IheartF5_45022's avatar
Dec 05, 2011

Using HTTP::collect from event HTTP_REQUEST_SEND

Hi!

 

 

I'm trying to modify the payload of a request on virtual server with ASM active (and performing WSS signature validation), so I need to perform my payload manipulation from HTTP_REQUEST_SEND, an event which operates in the serverside context. The doco says that HTTP_COLLECT should function from within this event, but I am having some trouble, and getting error message;

 

 

http_process_state_prepend - Invalid action EV_COLLECT during ST_HTTP_PREPEND_HEADERS (Client side: vip=/Common/vs_acg_test.com_http profile=http pool=/Common/pl_acg_test_http).

 

 

Here is my irule with a few bits removed;-

 

 

when HTTP_REQUEST_SEND {

 

 

clientside {

 

set debug 1

 

 

if { $debug>=1 } {log local0. "URI is [HTTP::uri]"}

 

 

if {[HTTP::path] eq "/app/CreditCardManagement/v1"} {

 

 

if { $debug>=1 } {log local0. "It's a card!"}

 

 

if {[HTTP::header Content-Length] > 40 } {

 

if { $debug>=1 } {log local0. "Collecting [HTTP::header Content-Length] bytes"}

 

 

HTTP::collect [HTTP::header Content-Length]

 

}

 

}

 

}

 

}

 

 

when HTTP_REQUEST_DATA {

 

This is the payload - find and mask the cardnumber

 

 

clientside {

 

if { $debug>=1 } {log local0. "Payload: [HTTP::payload]"}

 

 

if {[string length $cpan] <= 0} {

 

if { $debug>=1 } {log local0. "No CPAN - exiting"}

 

HTTP::release

 

return

 

}

 

 

You'll need this little number later when manipulating the encrypted string

 

set cnIndexStart [expr {12 + [string first ":CardNumber>" [HTTP::payload] 0] }]

 

if { $debug>=1 } {log local0. "Index start: $cnIndexStart"}

 

 

set cType [findstr [HTTP::payload] ":CardType>" 10 "<"]

 

if { $debug>=1 } {log local0. "cardtype is $cType"}

 

 

if {((($cType eq "MASTERCARD") | ($cType eq "VISA")) & ([string length $cpan] == 16)) | \

 

(($cType eq "AMEX") & ([string length $cpan] == 15))} {

 

 

card number has passed basic validation

 

Do secret stuff to cardnumber

 

 

Update payload with mask

 

HTTP::payload replace $cnIndexStart [string length $cpan] "XXXXXXXXXXXXXXXX"

 

if { $debug>=1 } {log local0. "All good. ContentLength: [HTTP::header Content-Length]"}

 

 

} else {

 

Update payload to indicate card format error

 

HTTP::payload replace $cnIndexStart [string length $cpan] "~10~"

 

if { $debug>=1 } {log local0. "Format error. ContentLength: [HTTP::header Content-Length]"}

 

}

 

 

if { $debug>=1 } {log local0. "Payload: [HTTP::payload]"}

 

 

HTTP::release

 

}

 

}

 

 

Can anyone tell me if ;-

 

 

a) I can do what I want to do in the serverside context

 

b) How to achieve it or any things to try

 

 

If the worst come to the worst I can always enable ASM on one virtual server and my iRule on another but that does seem rather clumsy given that the doco does say that I should be able to do what I want to.......

 

 

Also, I did try to enable the clientside context on a command by command basis rather than encapsulating the whole event logic within 'clientside' but got errors doing that too a la; "Dec 5 09:39:33 tmm err tmm[21496]: 01220001:3: TCL error: /Common/ir_acg_update_payload_sanitised - invalid command name "/app/CreditCardManagement/v1" while executing "[HTTP::uri]"invalid peer expression (line 1) invoked from within "clientside {[HTTP::uri]}"

 

 

Thanks!!

 

  • So I have (temporarily) given up on the HTTP::collect in HTTP_REQUEST_SEND functionality pending our account team poking the developers for a response, however I tried to setup 2 VIPs, (a frontend VIP using ASM, and a backend VIP using my iRule), and have the frontend invoke the backend one by placing the backend VIP IP in a pool, however it doesn't work :-(.

     

     

    Had a quick word with our local f5 guys, and invoking the backend VIP from the frontend by using an iRule with the command ;-

     

    virtual

     

    works a treat. Thanks local team!!