Forum Discussion

Spencer_Aranda's avatar
Spencer_Aranda
Icon for Altocumulus rankAltocumulus
Nov 18, 2022

Help deleting header name that contains curly braces

Hi

Just a quick question.  I was asked to use the F5 to remove a header name as follows {esbsoapheader}userName

The header value was just fine.  But I was asked to remove {esbsoapheader} from header name  {esbsoapheader}userName

I tried HTTP::header remove "{esbsoapheader}userName"   but it did not work.  I got an error as follows 

TCL error: /Common/ilxpi_demo/ilxir_demo <HTTP_REQUEST> - list element in braces followed by "userName" instead of space while executing "HTTP::header remove "{esbsoapheader}userName""

I'm guessing the header name has invalid characters, ie "{}"  Has anyone encountered something similar?  Is this header name ilegal/malformed? Is there a way I can remove this?

 

Any help is appreciated! thank you!

 

 

  • I think I just figured it out guys Mohamed_Ahmed_Kansoh  CA_Valli 

    Paste this and run it.  It worked out for me.  Now any of you can explain why this works??  Is this a bug with F5?  At least it seems to me.  If it is, how can I let them know so they can fix it.

    when HTTP_REQUEST {
      if { [HTTP::uri] eq "/demo2" } {
        HTTP::header insert "{esbsoapheader}userName" "spencer"
        foreach aHeader [HTTP::header names] {
          log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
        }
        log local0. "***************REMOVING BAD HEADER************"
        HTTP::header remove "\\{esbsoapheader\\}userName"
        foreach aHeader [HTTP::header names] {
          log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
        }
      }
    }
  • I think I just figured it out guys Mohamed_Ahmed_Kansoh  CA_Valli 

    Paste this and run it.  It worked out for me.  Now any of you can explain why this works??  Is this a bug with F5?  At least it seems to me.  If it is, how can I let them know so they can fix it.

    when HTTP_REQUEST {
      if { [HTTP::uri] eq "/demo2" } {
        HTTP::header insert "{esbsoapheader}userName" "spencer"
        foreach aHeader [HTTP::header names] {
          log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
        }
        log local0. "***************REMOVING BAD HEADER************"
        HTTP::header remove "\\{esbsoapheader\\}userName"
        foreach aHeader [HTTP::header names] {
          log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
        }
      }
    }
    • JRahm's avatar
      JRahm
      Icon for Admin rankAdmin

      Nice work, Spencer_Aranda! The reason you need this is to escape the special characters. Both "\" and "{ }" are special characters in Tcl, so the "\\{" pattern is to escape both so you can actual match as the string as intended.

    • Leslie_Hubertus's avatar
      Leslie_Hubertus
      Ret. Employee

      Hey Spencer_Aranda - what a great conversation you kicked off here!

      JRahm pointed out the special character thing, but to report a bug in the future, please contact F5 Support  and give them the details so they can create a report. ðŸ™‚

      (edited)

  • xuwen's avatar
    xuwen
    Icon for Cumulonimbus rankCumulonimbus

    Amazing thing in iRules, you can submit to the original factory that this is a bug to be optimized or that iRules has a strange bug with "{"  or  "}" in the HTTP header

    It may also be a disadvantage of the TCL language. Lists can be represented by "" or {}, which can sometimes be ambiguous, unlike Python lists, which can only be represented by []

    Some manufacturers' load balancing scripts use lua language instead of tcl

    I found that as long as the name field in the HTTP header contains {  or  }, HTTP:: header remove will report an error,

    It seems that HTTP:: header remove name, name value refers to the value in HTTP:: header names storage format, rather than the value of variable string that we usually understand

    log local0. "names is: [HTTP::header names]"          the log result is:

    names is: Host User-Agent Accept {{esbsoapheader}userName} Connection {{esbsoapheader}userName}

    HTTP header name {esbsoapheader}userName the storage format in [HTTP::header names] is {{esbsoapheader}userName}

    so, we need to use this format HTTP::header remove {{{esbsoapheader}userName}}     or     

    HTTP::header remove "{{esbsoapheader}userName}"

    use HTTP::header remove {{esbsoapheader}userName} will raise error!

    if we HTTP::header insert "\{esbsoapheaderuserName" "f5-gtm" 

    the [HTTP::header names] running result is:

    names is: Host User-Agent Accept \{esbsoapheaderuserName Connection

    we need to this format to remove:

    HTTP::header remove {\{esbsoapheaderuserName}

     

     

    It seems that in the list of tcl, the element storage that contains {  or  } needs to carry {}

    (bin) 49 % set a {Host User-Agent Accept {esbsoapheader}userName Connection}
    Host User-Agent Accept {esbsoapheader}userName Connection
    (bin) 50 % lindex $a 3
    list element in braces followed by "userName" instead of space
    (bin) 51 % string length $a
    57

    (bin) 53 % set a "Host User-Agent Accept {esbsoapheader}userName Connection"
    Host User-Agent Accept {esbsoapheader}userName Connection

    (bin) 55 % lindex $a 1
    list element in braces followed by "userName" instead of space
    (bin) 56 %

    (bin) 57 % set a {Host User-Agent Accept {{esbsoapheader}userName} Connection}
    Host User-Agent Accept {{esbsoapheader}userName} Connection

    (bin) 62 % lindex $a 3
    {esbsoapheader}userName

    (bin) 63 % set qq "Host User-Agent Accept {{esbsoapheader}userName} Connection"
    Host User-Agent Accept {{esbsoapheader}userName} Connection
    (bin) 64 % lindex $qq 3
    {esbsoapheader}userName
    (bin) 65 %

    (bin) 95 % set names_list {Host User-Agent Accept \{esbsoapheader\}userName Connection}
    Host User-Agent Accept \{esbsoapheader\}userName Connection
    (bin) 97 % lindex $names_list 3
    {esbsoapheader}userName
    (bin) 98 %

    (bin) 70 % set names "Host User-Agent Accept \\{esbsoapheader\\}userName Connection"
    Host User-Agent Accept \{esbsoapheader\}userName Connection
    (bin) 71 % lindex $names 3
    {esbsoapheader}userName

     

     

     

    when HTTP_REQUEST {
        if { [HTTP::uri] eq "/demo2" } {
            HTTP::header insert "\{esbsoapheaderuserName" "spencer"
            HTTP::header insert Connection close
            HTTP::header insert "{esbsoapheader}userName" "f5-bigip"
            foreach aHeader [HTTP::header names] {
                log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
            }
            log local0. "exists header: [HTTP::header exists "{esbsoapheader}userName"]; value is [HTTP::header "{esbsoapheader}userName"]"
            log local0. "names is: [HTTP::header names]"
            log local0. "***************REMOVING BAD HEADER************"
            
            # set a "{esbsoapheader}userName"
            # HTTP::header remove [list $a]
            
            # HTTP::header remove "{{esbsoapheader}userName}"  it also works correct
            HTTP::header remove {{{esbsoapheader}userName}}
            HTTP::header remove {\{esbsoapheaderuserName}
            foreach aHeader [HTTP::header names] {
                log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
            }
        }
    }

     

     

     

     

     

    • Thanks for sharing this! I thought the issue could be something like this but I did not have time to look into this further. 

      Well, you never stop learning! 😜 

  • Hi Spencer_Aranda , 
    Could you please specify if this header added at request or response time , also can you give a simulated sample to this header.
    I will follow up your request. 
    Regards 

  • Spencer_Aranda ,

    when HTTP_REQUEST { 
         HTTP::header remove "{esbsoapheader}userName"
       }

    it worked with me in my lab without errors , could you please share your irule script exactly. 

    Regards

  • Hi Mohamed,

    Thanks for your reply.  Here is the example.  I'm using this to test.  In the real scenario, the header name "{esbsoaheader}userName" was already found in the HTTP headers, but in this test scenario and I'm adding it and then trying to remove it.  I'm not sure how it worked for you.

     

    when HTTP_REQUEST {
     
    if { [HTTP::uri] eq "/demo2" } {

    HTTP::header insert "{esbsoapheader}userName" "spencer"

    foreach aHeader [HTTP::header names] {
    log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
    }

    log local0. "***************REMOVING BAD HEADER************"
    HTTP::header remove "{esbsoapheader}userName"
    foreach aHeader [HTTP::header names] {
    log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]"
    }
    }

    }

     

    LOGS

    TCL error: /Common/ilxpi_demo/ilxir_demo <HTTP_REQUEST> - list element in braces followed by "userName" instead of space while executing "HTTP::header remove "{esbsoapheader}userName""

     

     

     

     

    • Spencer_Aranda , 
      I have Copied it from your reply and tested the full script on my lab : 

      it runs well on my lab without errors , 
      What is your software version 
      I am on v15.1.0.4 what about yours , to see what are the differences with each release ? 

      • Spencer_Aranda's avatar
        Spencer_Aranda
        Icon for Altocumulus rankAltocumulus

         

        Hi Mohamed

        This is my set up.  The version is 16.1.3
        It is very strange that it works for you but not for me... Am I missing something here?

         

         

         

         

  • Hello, I'd love to help you out but this is turning out to be tricky.

    It's not possible to edit header name directly via iRule, so my code retrieves {esbsoapheader}userName value and inputs it into a new userName header. Then I'm attempting to delete {esbsoapheader}userName -- but this fails. I see iRule execution crashes and cllient connection is reset. 

    I've tried escaping curly braces with "\" as well, or passing it via a variable, but it doesn't seem to work. 

    Will it be enough to just insert userName? Is it a problem if {esbsoapheader}userName exists in request? 

    Sharing my progress so far. 

    when HTTP_REQUEST {
      if { [HTTP::header exists "{esbsoapheader}userName"] }{ 
           HTTP::header insert userName [HTTP::header "{esbsoapheader}userName"]
    # non-working code
    #       HTTP::header remove "{esbsoapheader}userName"
    #       HTTP::header remove "\{esbsoapheader\}userName"
    #       HTTP::header remove \{esbsoapheader\}userName
    #       set hnme "{esbsoapheader}userName" ;  HTTP::header remove $hname     
      }
    }

     

    • Spencer_Aranda's avatar
      Spencer_Aranda
      Icon for Altocumulus rankAltocumulus

      Thank you for taking the time to look into this CA_Valli 

      What you just showed to me is the fix that I gave the people that first asked me to remove {esbsoapheader} from header name. 

      I ended up just inserting a new header name just with userName and did not remove the bad header name.  However, this is not quite what they were looking for so that is why I came to the F5 forum to look for answers.  

      I'm extremely curious how it worked out for Mohamed_Ahmed_Kansoh  ...

    • Spencer_Aranda's avatar
      Spencer_Aranda
      Icon for Altocumulus rankAltocumulus

      CA_Valli  Do you know why it is not possible to remove "{esbsoapheader}userName"?  Is it because the header name is using characters that are not legal to use in a header name?  If so, do you have some resource that I can read to confirm?

      • it does not work with me , 
        I meant the iRule script is correct and accepted , I thought you have a problem with that. 
        No I have performed your script on my test lab and I saw the TCL error: 

        Let me see how can I remove it , if I found a workaround , definitely I will share it with you 

        Regards