Forum Discussion

R_Marc's avatar
R_Marc
Icon for Nimbostratus rankNimbostratus
Apr 28, 2014

Odd behavior on regsub in iRule

I have a switch in an irule to clean up some bad decisions made by developers.

Here is the trimmed down version where the problem occurs, with some debug logging.

ltm rule rmarc-test-rule {
    when HTTP_RESPONSE {
   Ferret out bad location headers
  switch -glob [HTTP::header values Location] {
        "*test*" - "*a401*" {
                log local0. "Header before: [HTTP::header values Location]"
                HTTP::header replace Location [regsub -all {(a401|test).somedomain.com} [HTTP::header values Location] dtl.somedomain.com]
        }
     }
     log local0. "Header after: [HTTP::header values Location]"

}
}

It works most of the time, but occasionally does this:

$ telnet mytestserver 80
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Date: Mon, 28 Apr 2014 22:42:25 GMT
Server: Apache
Last-Modified: Mon, 28 Apr 2014 18:35:59 GMT
ETag: "23-4f81e962e3c54"
Accept-Ranges: bytes
Content-Length: 35
Location: {https://dtl.somedomain.com/mypath}
Connection: close
Content-Type: text/html
Set-Cookie: BIGipServerrmarc-test-pool=3405159590.20736.0000; path=/


 Blah 

Connection closed by foreign host.

Notice the { } around the location header value. This breaks a 301/302. In my test here, I just set the location header using mod_header in apache to reproduce the issue.

If I do this regsub in tclsh, It doesn't do this.

I'm running 11.4.1 HF3-ish (special HF to address a bug).

It's quite confusing. The current work around was to just make the switch match more specific.

9 Replies

  • R_Marc's avatar
    R_Marc
    Icon for Nimbostratus rankNimbostratus

    Had a typo in my. The /mypath should read /mytest, which is how it hits the regsub.

     

  • Hi!

    Maybe this is not the answer you're looking for, in which case we can adjust it a bit.

    A few suggestions:

    • Try to avoid the -sub switch if you can as it demotes the LB to a use single core processing.
    • Use the is_redirect check to avoid using costly regsub commands in vain.

    A rule suggestion (providing that you will always replace the location with the same url):

    when HTTP_RESPONSE {
         Ferret out bad location headers   
        if { [HTTP::is_redirect] } {
            set location [string tolower [HTTP::header values Location]]
    
            if { $location contains "test" || $location contains "a401" } {
                log local0. "Header before: [HTTP::header values Location]"
                HTTP::header replace Location "dtl.somedomain.com"
                log local0. "Header after: [HTTP::header values Location]"          
            }
        }
    }
    

    /Patrik

  • R_Marc's avatar
    R_Marc
    Icon for Nimbostratus rankNimbostratus

    Doesn't quite do what I need, but the warnings duly noted. Thank you.

     

  • R_Marc's avatar
    R_Marc
    Icon for Nimbostratus rankNimbostratus

    The Location might be very specific (this is for WebSEAL).

    A rather simple example:

    Location: https://test.somedomain.com/jct_test/client-admin/login;jsessionid=260A8C73CC86423F53B625A0976FA6D6
    

    I have to chage that to:

    Location: https://dtl.somedomain.com/jct_test/client-admin/login;jsessionid=260A8C73CC86423F53B625A0976FA6D6
    

    That would be wicked simple in perl :).

    regsub does it except for the odd behavior I noted. If there is a better way to do that, I'm all ears.

  • wondering if string map is also applicable.

    e.g.

    HTTP::header replace Location [string map {a401.somedomain.com dtl.somedomain.com test.somedomain.com dtl.somedomain.com} [HTTP::header Location]]
    
  • wondering if string map is also applicable.

    e.g.

    HTTP::header replace Location [string map {a401.somedomain.com dtl.somedomain.com test.somedomain.com dtl.somedomain.com} [HTTP::header Location]]