Forum Discussion

silvajai_01_131's avatar
silvajai_01_131
Icon for Nimbostratus rankNimbostratus
Apr 18, 2016

iRule Redirect To Specific Pool Member Based On HTTP Header String

Greetings,

 

I apologize for my lack of iRule experience upfront. Our SME that normally handles the writing of specific iRules is out this week. I have been asked to write an iRule that will check incoming HTTP connections for a string named "X-SLOWROLL" = 1 condition. If the statement is true the connection should be sent to a specific pool member host and if its false it should be sent to the pool.

 

I don't have any iRule experience and need some help or advice with regards where to research for a base rule that would help me write one to meet the above requirement.

 

Any help or feedback would be greatly appreciated.

 

  • Sample iRule with Loggings:
    config  tmsh list ltm rule SLOWROLL
    ltm rule SLOWROLL {
        when HTTP_REQUEST {
     if { [HTTP::header exists X-SLOWROLL] and [HTTP::header X-SLOWROLL] equals "1" } {
        node 10.29.100.20 80
            set url [HTTP::header Host][HTTP::uri]
            set vip [IP::local_addr]:[TCP::local_port]
            foreach aHeader [HTTP::header names] {
          log local0. "HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]"
                    }
            }
    }
    when HTTP_RESPONSE {
            set client [IP::client_addr]:[TCP::client_port]
            set node [IP::server_addr]:[TCP::server_port]
            set nodeResp [HTTP::status]
            log local0.info "SUMMARY: Client: $client -> VIP name is [virtual name] $vip and URL is $url -> Node: $node with response $nodeResp"
     }
    }
    
    
    
    
    Request from a client:
     curl -v -H 'X-SLOWROLL: 1' http://150.29.100.98
    * About to connect() to 150.29.100.98 port 80 (0)
    *   Trying 150.29.100.98... connected
    * Connected to 150.29.100.98 (150.29.100.98) port 80 (0)
    > GET / HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1l zlib/1.2.3 libidn/0.6.5
    > Host: 150.29.100.98
    > Accept: */*
    > X-SLOWROLL: 1
    >
    < HTTP/1.1 200 OK
    < Content-Type: text/html
    < Last-Modified: Fri, 19 Sep 2014 09:29:52 GMT
    < Accept-Ranges: bytes
    < ETag: "7bf75a44ecd3cf1:0"
    < Server: Microsoft-IIS/7.5
    < Date: Tue, 19 Apr 2016 05:32:06 GMT
    < Content-Length: 1162
    
    
    Log output:
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1l zlib/1.2.3 libidn/0.6.5
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER Host: 150.29.100.98
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER Accept: */*
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER X-SLOWROLL: 1
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : SUMMARY: Client: 150.29.100.3:49555 -> VIP name is /Common/HSL_TEST_VS 150.29.100.98:80 and URL is 150.29.100.98/ -> Node: 10.29.100.20:80 with response 200
    
  • Sample iRule with Loggings:
    config  tmsh list ltm rule SLOWROLL
    ltm rule SLOWROLL {
        when HTTP_REQUEST {
     if { [HTTP::header exists X-SLOWROLL] and [HTTP::header X-SLOWROLL] equals "1" } {
        node 10.29.100.20 80
            set url [HTTP::header Host][HTTP::uri]
            set vip [IP::local_addr]:[TCP::local_port]
            foreach aHeader [HTTP::header names] {
          log local0. "HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]"
                    }
            }
    }
    when HTTP_RESPONSE {
            set client [IP::client_addr]:[TCP::client_port]
            set node [IP::server_addr]:[TCP::server_port]
            set nodeResp [HTTP::status]
            log local0.info "SUMMARY: Client: $client -> VIP name is [virtual name] $vip and URL is $url -> Node: $node with response $nodeResp"
     }
    }
    
    
    
    
    Request from a client:
     curl -v -H 'X-SLOWROLL: 1' http://150.29.100.98
    * About to connect() to 150.29.100.98 port 80 (0)
    *   Trying 150.29.100.98... connected
    * Connected to 150.29.100.98 (150.29.100.98) port 80 (0)
    > GET / HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1l zlib/1.2.3 libidn/0.6.5
    > Host: 150.29.100.98
    > Accept: */*
    > X-SLOWROLL: 1
    >
    < HTTP/1.1 200 OK
    < Content-Type: text/html
    < Last-Modified: Fri, 19 Sep 2014 09:29:52 GMT
    < Accept-Ranges: bytes
    < ETag: "7bf75a44ecd3cf1:0"
    < Server: Microsoft-IIS/7.5
    < Date: Tue, 19 Apr 2016 05:32:06 GMT
    < Content-Length: 1162
    
    
    Log output:
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1l zlib/1.2.3 libidn/0.6.5
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER Host: 150.29.100.98
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER Accept: */*
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : HTTP REQUEST HEADER X-SLOWROLL: 1
    Apr 18 15:33:36 MAMA-ATM-SGDC info tmm1[11293]: Rule /Common/SLOWROLL : SUMMARY: Client: 150.29.100.3:49555 -> VIP name is /Common/HSL_TEST_VS 150.29.100.98:80 and URL is 150.29.100.98/ -> Node: 10.29.100.20:80 with response 200
    
    • David_M's avatar
      David_M
      Icon for Cirrostratus rankCirrostratus

      Why do we need to do the for each here?

      foreach aHeader [HTTP::header names] {
            log local0. "HTTP REQUEST HEADER $aHeader: [HTTP::header value $aHeader]"
                      }
  • Hello,

    You can use something similar to this :

    when HTTP_REQUEST {
     if { [HTTP::header exists X-SLOWROLL] and [HTTP::header X-SLOWROLL] equals "1" } {
        node x.x.x.x 80
         node ip port
     }
    }
    
    • silvajai_01_131's avatar
      silvajai_01_131
      Icon for Nimbostratus rankNimbostratus
      Thanks. In my desperation, I came up with the below rule, which I haven't tested yet. Just curious, but do you think the below rule would have worked as well. when HTTP_REQUEST { set tcip [HTTP::header X-SLOWROLL] if { $tcip eq 1 } { node 10.16.18.1 80 } }
    • silvajai_01_131's avatar
      silvajai_01_131
      Icon for Nimbostratus rankNimbostratus
      when HTTP_REQUEST { set tcip [HTTP::header X-SLOWROLL] if { $tcip eq 1 } { node 10.16.18.1 80 } }
  • Hello,

    You can use something similar to this :

    when HTTP_REQUEST {
     if { [HTTP::header exists X-SLOWROLL] and [HTTP::header X-SLOWROLL] equals "1" } {
        node x.x.x.x 80
         node ip port
     }
    }
    
    • silvajai_01_131's avatar
      silvajai_01_131
      Icon for Nimbostratus rankNimbostratus
      Thanks. In my desperation, I came up with the below rule, which I haven't tested yet. Just curious, but do you think the below rule would have worked as well. when HTTP_REQUEST { set tcip [HTTP::header X-SLOWROLL] if { $tcip eq 1 } { node 10.16.18.1 80 } }
    • silvajai_01_131's avatar
      silvajai_01_131
      Icon for Nimbostratus rankNimbostratus
      when HTTP_REQUEST { set tcip [HTTP::header X-SLOWROLL] if { $tcip eq 1 } { node 10.16.18.1 80 } }