Forum Discussion

Eduardo_Saito_1's avatar
Eduardo_Saito_1
Icon for Nimbostratus rankNimbostratus
Jan 09, 2009

Modifying HTTP REQUEST DATA

Hello guys.

 

 

 

Every iRule I've made that need to access HTTP_RESPONSE_DATA I used the following code:

 

 

 
 when HTTP_REQUEST { 
     No Chunk 
    if { [HTTP::version] eq "1.1" } { 
       if { [HTTP::header is_keepalive] } { 
          HTTP::header replace "Connection" "Keep-Alive" 
       } 
       HTTP::version "1.0" 
    } 
 } 
  
 when HTTP_RESPONSE { 
    if { [HTTP::header exists "Content-Length"] } { 
       set content_length [HTTP::header "Content-Length"] 
    } else { 
       set content_length 1000000000 
    } 
    if { $content_length > 0 } { 
       HTTP::collect $content_length 
    } 
 } 
  
 when HTTP_RESPONSE_DATA { 
    log local0. "[HTTP::payload]" 
    HTTP::release 
 } 
 

 

 

But now I have to access the HTTP_REQUEST_DATA instead. The irule I've made looks like this one:

 

 

 
 when HTTP_REQUEST { 
     No Chunk 
    if { [HTTP::version] eq "1.1" } { 
       if { [HTTP::header is_keepalive] } { 
          HTTP::header replace "Connection" "Keep-Alive" 
       } 
       HTTP::version "1.0" 
    } 
  
     Colect Content_length 
    set clen [HTTP::header Content-Length] 
    if { not [info exists clen] or "" eq $clen } { 
       set clen 1000000000 
    } 
    HTTP::collect $clen  
 } 
  
 when HTTP_REQUEST_DATA { 
    log local0. "[HTTP::payload]" 
    HTTP::release 
 } 
 

 

 

It is working for the majority of the customers but some customers are complaining about not being able to reach WebServices (SOAP/XML). Their logs show connection reset.

 

 

The question is: Do I have to make a HTTP::version check at the HTTP_REQUEST even though I'm just interested in the HTTP_REQUEST_DATA? What might be the problem here?

 

 

 

Thanks for helping me.

 

3 Replies

  • When the TCP reset is sent to the client, do you see a TCL error logged to /var/log/ltm? If not, can you add logging to the iRule to see which event the reset is being sent during?

     

     

    And what are you doing with the content? If you're modifying the content, you could use a stream profile and STREAM::expression based iRule (Click here) to do it more efficiently. If you're making a load balancing decision, then you'll need to collect the payload.

     

     

    Aaron
  • Thanks for the reply hoolio.

    The only irule error I see is this one, but I have only this single entry in ltm log and he customer made several attempts.

    irule_log - Illegal argument (line 25) invoked from within "HTTP::collect $clen"

    The title is wrong I'm not modifying the HTTP Payload actually I'm using HTTP::payload for logging and statistics. Sorry about this.

    Do you think HTTP::version part is correct even though I'm interested only in the HTTP_REQUEST_DATA?

    Regarding logging TCP resets from this client I've made this iRule but I need to put it on a test environment.

      
      when CLIENT_ACCEPTED {  
         if { [IP::addr [IP::client_addr] equals 200.200.200.200] } {  
            log local0. "Just the client I want to debug: 200.200.200.200."  
            set debug 1  
         }  
      }  
        
      when HTTP_REQUEST {   
          No Chunk   
         if { [HTTP::version] eq "1.1" } {   
            if { [HTTP::header is_keepalive] } {   
               HTTP::header replace "Connection" "Keep-Alive"   
            }   
            HTTP::version "1.0"   
         }   
        
          Colect Content_length   
         set clen [HTTP::header Content-Length]   
         if { not [info exists clen] or "" eq $clen } {   
            set clen 1000000000   
         }   
         HTTP::collect $clen   
      }   
        
      when HTTP_REQUEST_DATA {   
         if { $debug == 1 }{  
            log local0. "Here comes the HTTP REQUEST PAYLOAD for 200.200.200.200..."  
            log local0. "[HTTP::payload]"   
         }  
         HTTP::release   
      }   
        
      when HTTP_RESPONSE {  
         if { [HTTP::header exists "Content-Length"] } {  
            set content_length [HTTP::header "Content-Length"]  
         } else {  
            set content_length 1000000000  
         }  
         HTTP::collect $content_length  
      }  
        
      when HTTP_RESPONSE_DATA {  
         if { $debug == 1 }{  
            log local0/ "Here comes the HTTP RESPONSE PAYLOAD for 200.200.200.200..."  
            log local0. "[HTTP::payload]"   
         }  
         HTTP::release   
      }  
        
      when CLIENT_CLOSED {  
         if { $debug == 1 }{  
            log local0. "Client 200.200.200.200 getting disconnected..."  
         }  
      }  
      

    Thanks again!
  • It would add significant overhead to collect the request/response for every client if you only want to log the payloads for one client. You should check if debug is set to 1 before modifying the version or collecting.

     

     

    You should also add a check to see if the request is a POST (or other methods which may have a payload).

     

     

    Can you add logging to the iRule and compare the log output from a failure and a success? Specifically, what is the value of $clen before you get the TCL error? Is it 0? You should add another check to see that $clen is greater than 0 before trying to collect the payload.

     

     

    Aaron