Forum Discussion

Mack_Hanson_107's avatar
Mack_Hanson_107
Icon for Nimbostratus rankNimbostratus
May 24, 2005

Recognize XML Request before Firing HTTP_REQUEST

I'm seeking a way to identify SOAP requests, to recognize them before the HTTP_REQUEST event fires, and then to bypass HTTP_REQUEST. Either that, or identify them in the first part of my HTTP_REQUEST rule. My existing HTTP_REQUEST rule does things like redirections and cookie evaluation -- which break the XML.

 

 

My current idea is to look for a leading XML element/signature common to SOAP, such as

 

 

 

 

and to do so in the CLIENT_DATA phase. Upon finding it, I'll direct the BIG-IP to serve the request without further inspection. Here is my existing rule (which is not working):

 

 

when CLIENT_ACCEPTED {

 

TCP::collect 200

 

}

 

 

when CLIENT_DATA {

 

if { [[TCP::payload] 200 contains "xml version"] }

 

{

 

log local7. "XML request"

 

 

abandon all further evaluation. Skip HTTP_REQUEST and

 

serve the request.

 

TCP::release

 

return

 

}

 

TCP::release

 

}

 

 

when HTTP_REQUEST {

 

Some actions that will break SOAP if it gets here

 

 

log local7. "WEB request"

 

 

Defeat conditional GETs on dynamic content

 

HTTP::header remove "If-Modified-Since"

 

HTTP::header remove "If-None-Match"

 

 

if { [HTTP::cookie exists oatmeal_cookie] != 1 }

 

{

 

HTTP::redirect "http://www.somewhere.com/"

 

return

 

}

 

}

 

1 Reply

  • You are on the right track. There are a few issues with your code but what really sticks out is the content checking of length 200. More than likely the HTTP headers will fill most of that buffer and not include the POST data which is what you are searching on. The easiest way I could think of filtering out SOAP requests would be to use the HTTP_REQUEST and HTTP_REQUEST_DATA events to interrogate the POST data directly and then perform whatever actions you want. From within the HTTP_REQUEST event, you have access to all of the HTTP headers and can search only in the POST content.

     

     

    Also, searching on "xml version" could return results for other POSTS that are uploading XML content. If you want to search specifically for SOAP messages, you should use part of standard SOAP requests. Here's the POST data for the iControl System::get_system_id() method.

     

     

     
        soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
       xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
       xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
        
                xmlns:namesp1="urn:iControl:System/SystemInfo" /> 
        
     

     

     

    Now, keep in mind that you need to be careful what identifiers you pick from here as some are dependent on the encoding method of the SOAP call (in this case rpc/enc - doc/lit is another popular option). Also, namespace prefixes can be anything that the client toolkit decides they should be. So, for example, searching for "

     

    If it were me writing this rule, I'd shy away from the CLIENT_DATA approach as you do not have a guarantee as to the content-lenght or the beginning of the POST data. I would go the HTTP_REQUEST route with something like the following:

     

     

    when HTTP_REQUEST { 
       HTTP::collect [HTTP::header Content-Length] 
     } 
      
     when HTTP_REQUEST_DATA { 
       if { [HTTP::payload] contains "http://schemas.xmlsoap.org/soap/envelope/" } { 
         log "SOAP Request" 
          return from this event and allow request through 
         return 
       } else { 
         log "Non-SOAP Request" 
         HTTP::header remove "If-Modified-Since"  
         HTTP::header remove "If-None-Match"  
        
         if { [HTTP::cookie exists oatmeal_cookie] != 1 } {  
            redirect client to new url and return from event. 
           HTTP::redirect "http://www.somewhere.com/"  
           return  
         }  
       } 
     }

     

     

    -Joe