Forum Discussion

Hans_Schneider2's avatar
Hans_Schneider2
Icon for Nimbostratus rankNimbostratus
Jul 10, 2007

Rewriting /aaa to /bbb and assigning pool transparently

Hi All,

 

 

I have a virtual server set up that I wish to add an irule for.

 

Basically the start of the uri will be used to choose the actual context on the actual servers in the pools.

 

 

I.e. in pseudo code, which I have been trying multiple variations of:

 

 


when HTTP_REQUEST {
 if { [HTTP::uri] starts_with "/aaa" } {
  HTTP::uri replace "/aaa" "/111"
  pool 111_pool
 }
 elseif { [HTTP::uri] starts_with "bbb" } {
  HTTP::uri replace "/bbb" "/222"
  pool 222_pool
 }
 elseif { [HTTP::uri] starts_with "ccc" } {
  HTTP::uri replace "/ccc" "/333"
  pool 333_pool
 }
 else {
   This is just here to catch the rest
  HTTP::redirect "https://[HTTP::host]/aaa[HTTP::uri]"
 }
}

 

So that the LTMs will send the request to one of the servers in the pools (they're set up fine btw) for example http://10.10.10.10/111/blah.html where /111 is set up on apache as a context.

 

 

Is it possible also so that I could do something for the returning traffic so that the end user doesn't notice the uri translation?

 

 

Thank you for your patience, and time.

 

Best regards,

 

 

 

5 Replies

  • You are pretty darn close with your pseudo code. Unfortunately, there isn't a "HTTP::uri replace" command. The best way to do it is with the "string map" command. I'd go something like this

     

     

    when HTTP_REQUEST {
      switch -glob [HTTP::uri] {
        "/aaa*" {
          HTTP::uri [string map { /aaa /111 } [HTTP::uri]]
          pool 111_pool
        }
        "/bbb*" {
          HTTP::uri [string map { /bbb /222 } [HTTP::uri]]
          pool 222_pool
        }
        "/ccc*" {
          HTTP::uri [string map { /ccc /333 } [HTTP::uri]]
          pool 333_pool
        }
        default {
          HTTP::redirect "https://[HTTP::host]/aaa[HTTP::uri]"
        }
      }
    }

     

     

    I prefer a switch statement as it's usually cleaner to read, but feel free to do an if/elseif with the starts_with operator if you prefer.

     

     

    The string map command will replace all occurrances (important to know if there are multiple occurrances of the first string) of the first string with the second string in the given value. So for the first case above, it will replace all occurrances of "/aaa" with "/111" in the value of [HTTP::uri] and will then return that value with is then assigned to the URI with the surrounding HTTP::uri command (brackets mean return the value, no brackets mean assign it).

     

     

    As for modifying the returned traffic, you can build that logic into the iRule by interrogating the HTTP::payload in the HTTP_RESPONSE and HTTP_RESPONSE_DATA events. The SSN Scrubber example in the CodeShare shows how to do this:

     

     

    http://devcentral.f5.com/Wiki/default.aspx/iRules/SocialSecurityNumberScrubbing.html

     

    Click here

     

     

     

    But, a far easier method would be to use the Stream profile (if you have it licensed). This thread talks about how to use the Stream profile

     

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&forumid=5&postid=13504

     

    Click here

     

     

     

    Hope this helps!

     

     

    -Joe
  • Excelent stuff man! Thanks a lot! I appreciate your help.

     

     

    Just stuck at the moment now with rewriting the url back from xx.xx.xx.xx/111/TheRest to /aaa/TheRest

     

     

    In answer to your question, yes, it is only the first occurance of /aaa, which led me to use the if elseif instead of the switch (which, you are absolutely correct in saying is the more efficient way).

     

     

    After collecting the HTTP::payload in the log file, I couldn't see anything referencing the uri... Also attempts to log out the HTTP::uri didn't work in the HTTP_RESPONSE or HTTP_RESPONSE_DATA contexts.

     

     

    Hmmm...

     

     

    I do have the stream profile available, so tomorrow morning I'll be looking into that.

     

     

    I'll let you know how I get on.

     

     

    Thanks a lot again.

     

    Best regards,
  • Oh, I thought you were talking about replacing all embedded links from the /aaa to /111. Per the HTTP protocol, the HTTP response does not return the URI back to the browser so there is no way on the response for you to tell the browser that you changed the URI on the backend. If you want the browser address bar to change, you will have to issue a full redirect back to the browser in the HTTP_REQUEST event instead of just modifying the URI before it gets to the backend server. This way the browsers address bar will be changed with your updated urls.

     

     

    Make sense?

     

     

    -Joe
  • I have a similar issue with a "One IP to many pools" type setup, However my front VIP is a redirect to port 443 so I am trying to do the iRule to pool after the redirect and it's not working. How can I keep the traffic redirected to 443 for a single IP to multiple pools, below is an example of my setup....

     

     

    VIP1 (www.xyz.com IP address 10.1.1.1):80---> redirect via iRule1 to port 443--->VIP2 (www.xyz.com IP address 10.1.1.1):443--->iRule2 setup to direct traffic to pools (pool1, pool2, pool3) if the traffic contains www.xyz.com/a (pool1), www.xyz.com/b (pool2), and www.xyz.com/c (pool3)...

     

     

    Brian