Forum Discussion

gamm_31377's avatar
gamm_31377
Icon for Nimbostratus rankNimbostratus
May 27, 2014

HTTP::payload replacement

Hello,

I try to modify a HTTP SOAP request from a client, because the used namespace is not correct (:i -> :xsi). The iRule is assigned to the virtual server. The replacement is correct, but when the ASM module is validating the XML it fails because the SOAP Request is to short.

I think the replacement of the payload does not work in the way I expect: HTTP::payload replace 0 [string length $newdata_1] $newdata_1

How can I exchange the payload against a larger buffer ?

Best Regards Jürgen

iRule to modify a SOAP request from a client

when RULE_INIT { set static::debug 1 }

when HTTP_REQUEST { Get the Content-Length Content-Length is only part of an POST, a GET has no Content_Length attribut

if Content-Length is > 1MB then set Content-Length to 1MB

if { [HTTP::header exists "Content-Length"] } { set content_length [HTTP::header "Content-Length"] } else { set content_length 0 } if { $content_length > 0 && $content_length < 1048577 } { set collect_length $content_length } else { set collect_length 1048576 }

if { $collect_length > 0 } { content_length != 0 if HTTP::collect was executed next step is the event HTTP_REQUEST_DATA HTTP::collect $collect_length } }

when HTTP_REQUEST_DATA {

if {$static::debug}{log local0. "payload before: [HTTP::payload $collect_length]"}

regsub -all ":i" [HTTP::payload] ":xsi" newdata_1

if {$static::debug}{log local0. "length newdata_1 : [string length $newdata_1]"}

replace the old payload with the new HTTP::payload replace 0 [string length $newdata_1] $newdata_1

if {$static::debug}{log local0. "payload after: $newdata_1"}

HTTP::release }

7 Replies

  • can you try this?

       HTTP::payload replace 0 [string length [HTTP::payload]] ""
       HTTP::payload replace 0 0 $newdata_1
    
  • can you try this?

       HTTP::payload replace 0 [string length [HTTP::payload]] ""
       HTTP::payload replace 0 0 $newdata_1
    
  • You should actually be able to get away with using a STREAM profile here. It'll be much faster than buffering request payload and you can also get rid of the regex.

    when HTTP_REQUEST {
        if { [HTTP::header Content-Type] contains "soap" } {
            STREAM::expression {@:i@:xsi@}
            STREAM::enable
        } else {
            STREAM::disable
        }
    }
    when HTTP_RESPONSE {
        STREAM::disable
    }
    

    One important caveat of using STREAM in an HTTP_REQUEST is that you need to force HTTP chunking. Create a new HTTP profile and set Request Chunking to "Rechunk". Add this HTTP profile and a generic empty STREAM profile to the VIP, along with this iRule.

  • It was not the length I got the following error:

     

    XML Buffer N/A Description Malformed document Document has no root element Context URL XML Profile XML_OSMCService

     

    POST /axis/services/OSMCService HTTP/1.1 User-Agent: kSOAP/2.0 SOAPAction: getGeneralInfoCollection Content-Type: text/xml Connection: close Host: 172.30.245.13 Accept-Encoding: gzip

     

    and the HTTP_REQUEST looks well formed:

     

    SYMAUTHNAAAACgAAABxvZ0ZJZnpHLzQ3Mk5jcXZqK0IxOFpKYWFvV1BrAAAADXBhbnplckBzeXN0ZW0AAAADAAAADFN1YmplY3RSb2xlcwAAAAIAAAAVT3BlblNjYXBlIFVDIEFwcDpUZWFtAAAABVVNOnVtAAAAD1N1YmplY3RQcm9maWxlcwAAAAIAAAAcT3BlblNjYXBlIFVDIEFwcDpUZWFtQHN5c3RlbQAAAAxVTTp1bUBzeXN0ZW0AAAAKRW50aXR5VHlwZQAAAAEAAAAEVXNlcgAAACFPcGVyYXRpb25hbERvbWFpbkBPU0NfVUNfVjZfTEFSR0UAAAAXQmFzaWNVc2VyQXV0aGVudGljYXRpb24AAAFGQ4Ki1AAAAUZDgnvwAAABRkO5kYAAAAFGRaf0AAAAAAxOb1N1YmplY3RLZXkAAAAISG1hY1NIQTEAAAAbSE1BQ0NoZWNrc3VtVmVyaWZpY2F0aW9uS2V5AAAAFF7NELFqp4PEjr38lTCebU6WkWKh6

     

  • Hello,

     

    how about if the payload is more than 1MB? in my case I need to replace let's say first and last lines in the request message...it's doing it for the first line but not for the last line ( I guess because it's only collecting 1MB of the message which miss out the last line)..any idea? thank you in advance.