Forum Discussion

John_LeMay_1062's avatar
John_LeMay_1062
Icon for Nimbostratus rankNimbostratus
Sep 27, 2006

Combining http_request and client_accepted?

I'm working on putting together what I think will be a relatively complex rule - at least it will be for me. So far my irule experience been limited to uri rewrites and redirects. However, I now have a need for something that will involve redirects, rewrites, and some additional logic. I believe I want to accomplish this all in one irule. Any tips would be welcome!

 

 

Here is what I am trying to accomplish:

 

 

- Client opens session to http://server

 

- When client accept, findstr against uri looking for "string"

 

- If "string" doesn't exist, change uri to what pool members expect to see

 

- Redirect client to https VS (using a client ssl profile to terminate ssl at LTM)

 

- Pool on https VS will consist of members listening on a non-std port

 

 

Some of what I want to do above would use when http_request, other parts would use when client_accept. Can these be somehow combined? References to using both in a rule I've seen in the forum seems to consistently result in errors.

 

 

Thank you!

6 Replies

  • Hi,

     

     

    The CLIENT_ACCEPTED event is triggered when a TCP connection is established (or UDP packet received?). It can be used for TCP (or UDP) level commands. The HTTP_REQUEST event is triggered when an HTTP profile is associated with the VIP and an HTTP request is received. It can be used for TCP (or UDP) and HTTP level commands.

     

     

    If you want to inspect the HTTP content (the URI) you should associate an HTTP profile on the VIP and use HTTP_REQUEST. In general, I think the only reason you would use CLIENT_ACCEPTED instead of HTTP_REQUEST is if you don't want the overhead of having TMM parse the HTTP and are just using lower layer functionality like making decisions based on the IP address or ports involved in the request.

     

     

    You can change the URI using 'HTTP::uri /new/uri'. You can send a redirect to using 'HTTP::redirect https://myhost/redirected.html'. TMM handles the port translation from what the client requested to the port of the node, if you have port translation enabled on the VIP.

     

     

    Aaron
  • Aaron,

     

     

    Thank you for the reply. Your explanation seemed to simplify matters somewhat. Based on that, I came up with the following irule. However, I'm not getting the desired results. I'm receiving an error in my browser indicating the page I'm requesting cannot be found.

     

     

    Based on what is below and on the configuration of the VS I described, I would expect when a client connects to "https://server" the LTM would request "http://server/path/path:81". That doesn't seem to be happening. I don't expect I still need a http redirect here. Am I wrong?

     

     

    I'd also like to simplify that if/elseif/else if anyone has a recommendation.

     

     

    when HTTP_REQUEST {

     

    set uri [HTTP::uri]

     

    if { $uri eq "" } {

     

    set uri "/path/path"

     

    pool pool_app_http81

     

    } elseif { $uri eq "/" } {

     

    set uri "/path/path"

     

    pool pool_app_http81

     

    } else { pool pool_app_http81 }

     

    }

     

     

  • The URI will never be an empty string. If you submit https://server, the browser will send a get for "/" the same as it would if you requested https://server/.

    So, in this case, your uri will never fall into the initial condition.

    Also, you are setting the "uri" variable to the new path, but you aren't assigning it with the "HTTP::uri" command.

    I'd suggest you throw in some logging statements to help yourself debug your logic. It's hard for us on our end to figure out exactly what your test environment is and most of the time logging will give you enough insight to figure it out for yourself.

    when HTTP_REQUEST {
      set uri [HTTP::uri]
      log local0. "URI is : $uri"
      if { $uri eq "" } {
        log local0. "URI is empty - this will never happen!"
        set uri "/path/path"
        pool pool_app_http81
      } elseif { $uri eq "/" } {
        log local0. "URI is a slash"
        set uri "/path/path"
        pool pool_app_http81
      } else { pool pool_app_http81 }
    }

    A few questions. In all of your conditions, you are specifying the pool pool_app_http81. Why not just do it once outside the if/else statements (or better yet, make that the default pool for the virtual). If you made the pool pool_app_http81 the default, then your rule would simplify to this

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

    No temporary variables and a single string comparison.

    If you don't want to specify a default pool, you could do it in one place:

    when HTTP_REQUEST {
      if { [HTTP::uri] eq "/" } {
        HTTP::uri "/path/path"
      }
      pool pool_app_http81
    }

    Hope this helps...

    -Joe
  • Wow, that greatly simplifies this process. I'm getting away from the original subject here, but I have one last piece of this and I believe I'll have a working site.

     

     

    As I mentioned previously, the http servers in this case are listening on an odd port - 81 to be exact. We want the clients to connect via https. What I have done so far is configured a VS that listens on 443, has a client SSL profile, and has the irule and a pool as resources. The pool has two members, both listening on port 81.

     

     

    What I expected was the client would always talk to the BigIP via https and all of the port 81 "stuff" would be handled behind the scenes. What is happening now is the client is being redirected to http://server/path/path:81. I'm not completely certain yet if this maybe a behavior of the application instead of a BigIP issue.

     

     

    Should there be a simple way to accomplish what I'm describing, or am I going to be stuck running multiple virtual servers and not being able to run the client side over https?
  • This is what the rewrite redirects option on the HTTP profile was designed to handle. When a node sends an HTTP 3xx redirect, TMM can rewrite the Location header from HTTP to HTTPS.

     

     

    Check the config guide for your version for more info:

     

     

    Rewriting an HTTP redirection

     

    Click here

     

     

    Or you can get more detail in the online help in the HTTP profile section of the GUI.

     

     

    Aaron
  • Just wanted to follow up on this and thank everyone for the help! I still don't have the https piece working yet, but everything else is working. My rule ended up being a simple redirect instead of the complex beast I thought it would be.