Forum Discussion

KimiLi_147173's avatar
KimiLi_147173
Icon for Nimbostratus rankNimbostratus
Jan 09, 2017

How to make a http switching iRule that can deal with websocket requests?

Hi all,

We use a http switching iRule which is associated with a http profile on LTM 11.2.0, to transfer traffic to different pools according to URL of the requests, in order to save IP addresses, the iRule is like this:

when HTTP_REQUEST { 

 Check requested host header (set to lowercase) 
switch [string tolower [HTTP::host]] { 

   "fsbp.abc.com" { 
      pool pool_fsbp.abc.com_dmz 
   } 
   "vwcc.abc.com" { 
      pool pool_vwcc.abc.com_dmz 
   } 
   "afms.abc.com" { 
      pool pool_afms.abc.com_80_dmz 
   }
   "kf1.abc.com" { 
      pool pool_kf1.abc.com_80_dmz 
   } 
   "kf2.abc.com" { 
      pool pool_kf1.abc.com_80_dmz 
   } 
  } 
}

The issue is the web application with hostname both "kf1.abc.com" and "kf2.abc.com" is using websocket, it seems that websocket requests cannot be recognized or be transfered to the expected pool.

I didn't find the topic which can solve my issue, so I wonder what should the iRule be like that can transfer both http traffic and websocket traffic?

Any help would be thankful.

2 Replies

  • http profile does not understand websocket protocol. After websocket handshake, you must disable http: Add the following code the bottom of your irule :

     

    if { [string tolower [HTTP::header Upgrade]] contains "websocket" }{
          HTTP::disable
    }
  • If you upgrade to at least 11.5 there is "native support" for Web sockets. I assume the you get connection reset when you try the rule above?

    The problem is that the initial request from the client is over HTTP but then the connection gets "upgraded" and suddenly the F5 is not able to decipher the traffic from the client.

    Since you're basing your pool decisions on host header it means that whenever the browser wants to connect to a resource in a different pool a new connection must be opened anyway, so there would be no critical loss in disabling HTTP after choosing the pool (unless you have other rules, policies etc depending on http profiles).

    If you're lucky this might work:

    when HTTP_REQUEST { 
    
     Check requested host header (set to lowercase) 
        switch [string tolower [HTTP::host]] {
    
            "fsbp.abc.com" { 
                pool pool_fsbp.abc.com_dmz
            } 
            "vwcc.abc.com" { 
                pool pool_vwcc.abc.com_dmz 
            } 
            "afms.abc.com" { 
                pool pool_afms.abc.com_80_dmz 
            }
            "kf1.abc.com" { 
                pool pool_kf1.abc.com_80_dmz 
            } 
            "kf2.abc.com" { 
                pool pool_kf1.abc.com_80_dmz 
            } 
      }
      After choosing the pool, disable the HTTP profile.
      HTTP::disable
    }
    

    Hope that helped.

    /Patrik