Forum Discussion

InderS's avatar
InderS
Icon for Nimbostratus rankNimbostratus
Feb 04, 2020

iRule to remove Headers which have whitespaces

Hi all,

 

I have an HTTP response which has a few headers like these:

 

<process name:sample den

<process type:bikole

<pragma:i224242

 

I am trying to write an iRule to remove these headers - "process name" & "process type".

Here are iRules I tried, but none of them work. Interestingly both of them work on "pragma" ( because there is no whitespace in the header name):

 

iRule#1

 

when HTTP_RESPONSE {

   HTTP::header remove "process name"

   HTTP::header remove "process type"

HTTP::header remove "pragma"

}

 

OUTPUT: pragma removed but "process name" & "process type" still there

 

iRule#2

 

when HTTP_RESPONSE {

 foreach aheader [HTTP::header names] {

   log local0. "Header Name: $aheader"

   if { $aheader contains "process" } {

     log local0. "Header Removed: $aheader"

     HTTP::header remove $aheader

   }

 }

}

 

OUTPUT: "process name" & "process type" were not removed.

loggers:

 

Header Name: process

Header Removed: process

Header Name: name

Header Removed: name

Header Name: process

Header Removed: process

Header Name: type

Header Removed: type

 

Need urgent help to remove these pls. Can someone help?

 

4 Replies

  • That's going to be difficult using HTTP::Header, because with that space in them, they are not technically headers within the RFC specification. This confuses the HTTP parser, so the irule does not work.

     

    Your best approach is to use TCP::collect and the SERVER_DATA event, and a stream match to replace or remove part of the TCP payload from the pool member.

     

    • InderS's avatar
      InderS
      Icon for Nimbostratus rankNimbostratus

      Thanks for your prompt reply. Can you please help with some samples?

      • Simon_Blakely's avatar
        Simon_Blakely
        Icon for Employee rankEmployee

        This irule uses TCP::collect and TCP::payload to change the header names to ones without a space so they can be deleted:

        when HTTP_RESPONSE {
          HTTP::header remove "process_name"
          HTTP::header remove "process_type"
          HTTP::header remove "pragma"
        }
         
        when SERVER_CONNECTED {
         TCP::collect
        }
         
        when SERVER_DATA {
         log local0. "in SERVER_DATA [TCP::payload]"
         
         set header_1 [regexp -all -inline -indices {process name} [TCP::payload]]
         set header_1_start [lindex [lindex $header_1 0] 0]
         set header_1_end [lindex [lindex $header_1 0] 1]
         set header_1_length [expr ($header_1_end - $header_1_start) + 1]
         log local0. "process name occurs at byte $header_1_start, length $header_1_length"
         TCP::payload replace $header_1_start $header_1_length {process_name}
         
         set header_2 [regexp -all -inline -indices {process type} [TCP::payload]]
         set header_2_start [lindex [lindex $header_2 0] 0]
         set header_2_end [lindex [lindex $header_2 0] 1]
         set header_2_length [expr ($header_2_end - $header_2_start) + 1]
         log local0. "process type occurs at byte $header_2_start, length $header_2_length"
         TCP::payload replace $header_2_start $header_2_length {process_type}
         
         TCP::release
        }

        It could be written in a more efficient way, but this hopefully makes it clear at each step what is happening. You should also only collect enough SERVER_DATA to get the headers that you want to manipulate, rather than collecting the entire TCP response which could be expensive on memory.

  • Have a look at the stream profile, its probably the simplest way to do what you want