Forum Discussion

Mike_Sullivan_2's avatar
Mike_Sullivan_2
Icon for Nimbostratus rankNimbostratus
Dec 10, 2014

iRule using TCP::collect and TCP::payload to fix blanks (spaces) in HTTP request

Hi

I have a request to help fix mal-formed links. After some research, it looks like an irule around the CLIENT_ACCEPTED and CLIENT_DATA events utilizing the TCP commands is the way to fix it.

I wrote a rule that seems to "work", except that when it processes the request and has finished its job, the front end connection request times out. tcpdump on the backend shows that the sever side connection is never made. Below is the rule:

    when CLIENT_ACCEPTED {
log local0. "-"
    TCP::collect 200
}

when CLIENT_DATA {
log local0. "-"
    if { [TCP::payload 28] contains "GET /?engine=google&s_kwcid=" } { 
log local0. "Google Keyword Match"
        set mymatch [findstr [TCP::payload] "GET" 0 "\r\n"]
             set mybal [findstr [TCP::payload] "\r\n" 0]
             set myfields [split $mymatch " "] 
             if { [llength $myfields] > 3 } { 
log local0. "Found Blanks in Request"
                set mynewreq [concat [lindex $myfields 0] [join [lrange $myfields 1 end-1] "+"] [lindex $myfields end]]
log local0. "Request Fixed : $mynewreq"
        } else { 
log local0. "No Blanks in Request"
                set mynewreq $mymatch 
        }

             TCP::payload replace 0 [TCP::payload length] ""
             TCP::payload replace 0 0 [concat $mynewreq $mybal]
log local0. "TCP::payload -> [TCP::payload]"
             TCP::release
             TCP::collect

       }    
    }

Any idea on why the sever side connection is not made?

Thanks, Mike

  • it seems \r\n\r\n is removed when using concat.

    can you try this? it looks okay here.

    TCP::payload replace 0 0 "[concat $mynewreq $mybal]\r\n\r\n"
    
  • it seems \r\n\r\n is removed when using concat.

    can you try this? it looks okay here.

    TCP::payload replace 0 0 "[concat $mynewreq $mybal]\r\n\r\n"
    
  • it seems \r\n\r\n is removed when using concat.

    can you try this? it looks okay here.

    TCP::payload replace 0 0 "[concat $mynewreq $mybal]\r\n\r\n"
    
    • nitass's avatar
      nitass
      Icon for Employee rankEmployee
      concat trims whitespace http://wiki.tcl.tk/1037
  • The final(ish) version is this:

    when CLIENT_ACCEPTED {
    log local0. "-"
        TCP::collect
    }
    
    when CLIENT_DATA {
    log local0. "-"
        if { [TCP::payload 28] contains "GET /?engine=google&s_kwcid=" } { 
    log local0. "Google Keyword Match"
            set mymatch [findstr [TCP::payload] "GET" 0 "\r\n"]
                 set mybal [findstr [TCP::payload] "\r\n" 0]  
                 set myfields [split $mymatch " "] 
                 if { [llength $myfields] > 3 } { 
    log local0. "Found Blanks in Request"
                    set mynewreq "[concat [lindex $myfields 0] [join [lrange $myfields 1 end-1] "+"] [lindex $myfields end]]"
    log local0. "Request Fixed : $mynewreq"
            } else { 
    log local0. "No Blanks in Request"
                    set mynewreq $mymatch 
            }
    
                 TCP::payload replace 0 [TCP::payload length] ""
                 TCP::payload replace 0 0 "[concat $mynewreq $mybal]\r\n\r\n"
                 TCP::payload replace 0 0 "$mynewreq$mybal\r\n\r\n"
    log local0. "TCP::payload -> [TCP::payload]"
    
           }    
              TCP::release
              TCP::collect
    
        }
    

    The trick, as nitass identified, is concatenating the resulting strings w/out squeezing white-space needed to be compliant with the protocol. I ended up avoiding concat altogether, and it works, but I'm afraid of it working on a fluke and possibly breaking after an upgrade. Is it valid syntax to build the payload like this?:

    TCP::payload replace 0 0 "$mynewreq$mybal\r\n\r\n"

    If this is supported, I'm fine with it. If there is a better way to do it, I'm open to hear it. How have others solved this problem?

    Thanks for any insights.

    Mike

  • TCP::payload replace 0 0 "$mynewreq$mybal\r\n\r\n"

     

    have you tried it without \r\n\r\n? i think it is included in mybal.

     

    for the syntax, i think it is okay.

     

    by the way, what was the problem if using HTTP_REQUEST instead of CLIENT_ACCEPTED/CLIENT_DATA?

     

  • have you tried it without \r\n\r\n?

     

    Yes, it didn't work w/out the tacked on cd/lf, good thought though.

     

    what was the problem if using HTTP_REQUEST?

     

    That is the key! If the request gets up to the ASM or even a VIP w/ a http profile, we already have a protocol violation and I couldn't find a way to fit it. The HTTP:: attributes could not be modified so far as I can tell. Trying to find other examples on devcentral led me to this approach.

     

    Thanks Nitass!

     

    Cheers, Mike