Forum Discussion

Robert_47833's avatar
Robert_47833
Icon for Altostratus rankAltostratus
Jul 22, 2015
Solved

disable irule process for the request not for the whole tcp connection

hi ,Iurle I need to stop irule process for the exact http request ,not for the whole tcp connection ,how to achieve this?

 

  • Understood this topic is discussing some race conditions applied on iRule http events;

    client 1 --> http request1 --> F5 --> http request1 --> server
    client 1 --> http request2 --> F5 --> http request2 --> server
    client 1 --> http request3 --> F5 --> http request3 --> server
    client 1 <-- http request1 <-- F5 <-- http response1 <-- server
    client 1 <-- http request2 <-- F5 <-- http response2 <-- server
    client 1 <-- http request3 <-- F5 <-- http response3 <-- server
    

    From LTM perspective, LTM will not process the subsequent request (but rather put it on the request queue instead)until first response is back from backend pool memeber.

    Even pipelining is enabled on client side and multiple requests come in at same time, LTM will still serialize them and process them according to the sequence (FIFO).

    So in our case, variable has been set in request 1 will not be messed up even request 2 comes in earlier than response 1.

21 Replies

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    Maybe if you describe what you are trying to accomplish in a little more detail we might be able come up with a solution.

     

  • What I'm saying is that all of the HTTP_REQUEST events from all of the iRules are getting compiled into ONE HTTP_REQUEST event. So for something like this:

    iRule 1:

    when HTTP_REQUEST {
        set disable 0
    
        if { something } {
            set disable 1
        }
    }
    

    iRule 2:

    when HTTP_REQUEST {
        if { ( [info exists disable] ) and ( $disable == 1 ) } {
            do something else
        }
    }
    

    When you add both iRules to the same VIP, they're compiled into a single iRule with the logical equivalent of this:

    when HTTP_REQUEST {
        set disable 0
    
        if { something } {
            set disable 1
        }
    
        if { ( [info exists disable] ) and ( $disable == 1 ) } {
            do something else
        }
    }
    

    In other words, all of the HTTP_REQUEST event logic in all of the iRules will be executed before any response.

    But as giltjr recommends, maybe it'd be better if you could elaborate on what you're trying to do.

  • rule irule1 {
    
    when HTTP_REQUEST {
      set irule_skip 0
    
      if { conditions } {
         pool http
         set irule_skip 1
     }
    }
    }
    
    rule irule2 {
    
    when HTTP_REQUEST {
      if { $irule_skip } {
        return
      }
    }
    }
    

    what I ask is:

    suppose there are http request traffic from client to F5

    1:when the first http request traffic hit irule ,and set irule_skip as 0 then F5 distribute this request to backend server. 2:before backend server respond this first request traffic, the second http request traffic hit this VIP . 3:so the variable irule_skip is reset by the second http request traffic, right?

    http request traffic: the real request, not the event in irule.

  • so the variable irule_skip is reset by the second http request traffic, right? http request traffic: the real request, not the event in irule.

     

    Ah, then yes.

     

  • The response doesn't matter here, unless you're setting some flag based on a response. Each client HTTP request will trigger the HTTP_REQUEST event. The request and its corresponding response are atomic (usually).

     

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    So you are expecting the following:

    • client 1 --> http request1 --> F5 --> http request1 --> server
    • client 1 --> http request2 --> F5 --> http request2 --> server
    • client 1 --> http request3 --> F5 --> http request3 --> server
    • client 1 <-- http request1 <-- F5 <-- http response1 <-- server
    • client 1 <-- http request2 <-- F5 <-- http response2 <-- server
    • client 1 <-- http request3 <-- F5 <-- http response3 <-- server

    And you want to set a variable for http request 1 to use in http response 1 and not have http request 2 mess the variable up?

    When pipelining is use http responses must be sent int request order that is using the above response 3 can not be sent before response 1 and 2 are sent.

    Since variables are per connection what I would suggest is you number the variables. Something along the lines: Please note I have NOT tested this. If iRules (or TCL) had a FIFO stack/queue function you could use that and it would be easier. The only time I know there would be an issue is if a HTTP request and HTTP response were being processed at almost the same exact time.

        when CLIENT_ACCEPTED {
            set seq = 0
            }
    
        when HTTP_REQUEST {
           set $seq = $seq + 1
           set var.$seq = "to something"
           }
    
        when HTTP_RESPONSE {
        if {$seq = 1 } then {
            "do something with $var.$seq"
            $seq = 0
            }
        else {
            set invseq = 1
            "do something with $var.$invseq"
            while {$seq > 1} {
            set $prev = $invseq + 1
            set $var.$invseq = $var.$prev
            set $seq = $seq - 1
            }
        }
    }      
    
  • for example : when http response1 is not arrives, http request 2 arrives,then request 2 may set the variable to another value ,which I don't want to happen.becasue http response 1 still need to use variable set in http request 1. I am not sure how multiple http requests are sent in one tcp connection. If http request 2 is send after http response 1 is send back to client ,it will not cause issue

     

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    The iRule sample I gave above should add a sequence number to a variable name so that each outstanding http request has its own values. That way if you have 3 outstanding http requests you would have 3 variables: var.1, var.2, var.3. The value for var.1 is for the 1st request. When request1 response comes back, the code should use that variable. Then set var.1 to the values of var.2, set var.2 to the value of var.3 and set the value of $seq to 2, so that now you have var.1 and var.2 because you now only have two outstanding http request.

     

    They introduced HTTP pipelining, a process where a single TCP connection can have multiple HTTP request send without having to wait for a response. But the responses must be sent in the same order of the requests. Read: https://en.wikipedia.org/wiki/HTTP_pipelining

     

    However, I still think I'm missing something. You seem to only care about the 1st http request on a TCP connection. That is, where I have multiple variables (one for each request) only care about the 1st http request on a TCP connection. You do realize that a HTTP session can span multiple TCP connections and so each TCP connection will have its own unique "first HTTP request." So if a HTTP session say has 20 unique TCP connections, you will have "20 first http requests."

     

  • Understood this topic is discussing some race conditions applied on iRule http events;

    client 1 --> http request1 --> F5 --> http request1 --> server
    client 1 --> http request2 --> F5 --> http request2 --> server
    client 1 --> http request3 --> F5 --> http request3 --> server
    client 1 <-- http request1 <-- F5 <-- http response1 <-- server
    client 1 <-- http request2 <-- F5 <-- http response2 <-- server
    client 1 <-- http request3 <-- F5 <-- http response3 <-- server
    

    From LTM perspective, LTM will not process the subsequent request (but rather put it on the request queue instead)until first response is back from backend pool memeber.

    Even pipelining is enabled on client side and multiple requests come in at same time, LTM will still serialize them and process them according to the sequence (FIFO).

    So in our case, variable has been set in request 1 will not be messed up even request 2 comes in earlier than response 1.

  • giltjr's avatar
    giltjr
    Icon for Nimbostratus rankNimbostratus

    Robert do you have a oneconnect profile for the virtual server? If so, then Kiozs is correct, oneconnect does not support http pipeling. However, I'm not so sure what happens if you don't have a oneconnect profile.