Forum Discussion

webguy9_97931's avatar
webguy9_97931
Icon for Nimbostratus rankNimbostratus
May 22, 2007

iRule proxy

Hello,

 

 

I am looking to proxy requests based on:

 

 

1) UserAgent (bot detection)

 

2) URL patterns (foo\.html)

 

 

How do I set up the iRule to handle this?

 

 

Thanks!

9 Replies

  • For bot detection, here is a sample in CodeShare that shows how to detect a bot via the "User-Agent" http header.

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/ControllingBots.html

     

    Click here

     

     

     

    As for url patterns, the easiest way is to use a switch statement with file globbing (star based wildcards)

     

     

    when HTTP_REQUEST {
      switch -glob [HTTP::uri] {
        "*foo.html" {
           do something
        }
        "/path/*" {
           do something else
        }
        "/dir1/*" -
        "/dir2/*" -
        "/dir3/*" {
           do something if either of the above 3 match.
        }
      }
    }

     

     

    The basics here is that the URI is available with the HTTP::uri command in the HTTP_REQUEST event. You can assign that to a variable and do if/else statements, a switch statement (shown above), a match to a class list (as shown in the ControllingBots sample code).

     

     

    Hope this helps...

     

     

    -Joe
  • Thanks Joe...

     

     

    This is great!!

     

     

    Newbie Questions for ya...How do I proxy the request then? For example..above you say do something else. I am looking for the syntax.

     

     

    Thanks in advance..
  • You are going to have to tell me what you mean by "proxy". If you mean, send the traffic to a particular pool of servers, you can do that with the "pool" command. You can use the node command to send the request to a specific node:port destination. Check out the iRules wiki for the node and pool commands and you should see some examples. If that doesn't get you what you want, let me know exactly what you want accomplished when a match is found and I'll see what I can do to help you.

     

     

    -Joe
  • I am looking to send the request to another host. For example: if www.foo.com\bar.html comes in I want to detect that pattern (*.\html) and proxy to www.anotherserver.com.

     

     

    From your examples above I see how to detect the pattern and bots...just need to know how to actually send the request to the new server in a completely different domain.

     

     

    Thanks for the help.

     

  • 
    when HTTP_REQUEST {
      switch -glob [HTTP::uri] {
        "*foo.html" {
          HTTP::redirect "www.anotherserver.com"
        }
        "/path/*" {
          HTTP:redirect "www.yetanotherserver.com"
        }
        "/dir1/*" -
        "/dir2/*" -
        "/dir3/*" {
          HTTP::redirect "www.yetagainanotherserver.com"
        }
      }
    }
  • Thanks for the responses. This is a great forum!

     

     

    One last Q. In Apache I would use a MOD__REWRITE to rewrite the URI. In IIS I would use ISAPI_REWRITES to rewrite.

     

     

    I see how I can redirect (which gives a 302 in the header). I would like to proxy a request in F5. This is how it was explained to me:

     

     

    "You use a proxy when you want to control processing of the call from the point you receive it, and forward. A proxy can see the provisional and final responses to the request. It can record route so that it sees whats going on during the call. A redirect, however, hands off control to the device that sent. It will never see the final response to the request, and not be contacted again for the remainder of the call. Its a one-shot deal."
  • As long as the backend servers are running both host applications and accept both domains then you can modify the Host header with

    HTTP::header replace "Host" "www.host2.com"

    This will effectively change the host header to effectively change the url from http://www.host1.com/foo to http://www.host2.com/foo. You can also use the "HTTP::uri" command to modify the URI that is sent to the backend server.

    HTTP::uri "/path2"

    This would change the request from http://www.host1.com/path1 to http://www.host1.com/path2.

    A redirect is typically needed if control needs to be passed to a resource outside the scope of the proxy.

    If this doesn't give you enough of what you need, if you can specify exactly what you want the BIG-IP to do (ie, all inputs and all outputs and where the output is to go) I can try to get you something more concrete.

    -Joe
  • Hi Joe... I have been working with webguy9. What needs to happen is everytime a bot or a particular URI pattern occurs in any HTTP_REQUEST, we need to proxy that request to a completely different domain (hosted at a 3rd party site)

     

     

    Here is what we have right now:

     

     

    when HTTP_REQUEST {

     

    if { [matchclass [HTTP::host] equals $::SomeHost] } {

     

    if { not ([matchclass [string tolower [HTTP::header User-Agent]] contains $::Bots] or [matchclass [string tolower [HTTP::uri]] contains $::SomeURI]) } {

     

    pool SomePool

     

    }

     

    else

     

    {

     

    HTTP::redirect "http://3rdpartysite.com[HTTP::uri]"

     

    }

     

    }

     

    }

     

     

    So basically what needs to be different is the HTTP::redirect... would replacing it with this line be suffucient?

     

    HTTP::header replace "Host" "http://3rdpartysite.com[HTTP::uri]"

     

     

    Thanks
  • If it's hosted at a 3rd party site, then unless it's contained in the default pool, simply replacing the headers won't do much aside from "tricking" the existing backend webserver that the request came to it with a different URI. If you need to send the client to another resource that is not in the BIG-IP's load balancing configuration, you are going to have to rely on a HTTP::redirect which sends a 302 response back to the browser with a Location header specifying that it should re-request the page from the new URL.

     

     

    -Joe