Forum Discussion

Shridhar_84609's avatar
Shridhar_84609
Icon for Nimbostratus rankNimbostratus
Aug 25, 2009

Redirecting the URI

Hello,

 

 

I have a requirement to do the following -

 

 

http://abc.com/timesheets

 

should fetch the data from -

 

http://server1.com:30945/GroupServer/en/

 

 

http://abc.com/

 

should fetch the data from -

 

http://server2.com:40702/primaveraweb

 

 

where server1 & server2 are internal servers & abc.com is the virtual server to be configured on the Big-IP.

 

 

Please advise.

 

 

Regards,

 

Shridhar

6 Replies

  • Hi Shridhar,

    LTM's virtual server and pool configuration will handle the server selection and port translation with the default settings. If you want to select server1 you could add it to its own pool timesheet_http_pool. For all other requests, you could create a second HTTP pool. The advantage to using two separate pools versus hardcoding the IP addresses in the iRule is that you can add new members to the pool or change the server by modifying the pool--not changing the iRule.

    You could then use an iRule like this to select the pool and rewrite the requested URI:

     
     when HTTP_REQUEST { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: "New [HTTP::method] request to [HTTP::host][HTTP::uri]" 
      
         Check if requested path starts with /timesheets 
        if {[HTTP::path] starts_with "/timesheets"}{ 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: Matched /timesheets check" 
           pool timesheets_http_pool 
      
            Rewrite path if path is exactly /timesheets 
           if {[HTTP::path eq "/timesheets"}{ 
      
               Rewrite path 
              HTTP::path "/GroupServer/en" 
              log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to /GroupServer/en" 
           } 
        } else { 
      
            Use default HTTP pool 
           pool default_http_pool 
      
           log local0. "[IP::client_addr]:[TCP::client_port]: Using default_http_pool" 
      
            Rewrite path if path is exactly /timesheets 
           if {[HTTP::path eq "/"}{ 
      
               Rewrite path 
              HTTP::path "/primaveraweb" 
              log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to /primaveraweb" 
           } 
        } 
     } 
     

    Aaron
  • Hi Aaron,

     

     

    Thanks for the reply. I forgot to tell you that access to the root directory browsing has been disabled on these servers.

     

    ie.., If I want to access these servers directly (bypassing the Big-IP) I can only access -

     

     

    http://server1.com:30945/GroupServer/en/

     

    &

     

    http://server2.com:40702/primaveraweb

     

    and nothing else.

     

     

    In short, I CANNOT access the data just by typing http://server1.com:30945/ nor http://server2.com:40702/ in the browser. I need to type the full URL to get the content.

     

     

    I believe the below if statement in your suggested iRule will not work -

     

     

    if {[HTTP::path] starts_with "/timesheets"}{

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Matched /timesheets check"

     

    pool timesheets_http_pool

     

     

    because, this would just make the Big-IP try to fetch the data from http://server1.com:30945/ & NOT from http://server1.com:30945/GroupServer/en/.

     

     

    Also, the same goes with the 'else' statement -

     

     

    else {

     

    pool default_http_pool

     

     

    Hope, I am clear in my explanation.

     

     

    I tried the following iRule (without logging), and I was able to make it only the 'timesheets' part work but NOT the 'primaveraweb' part -

     

     

    b rule abc_com_rule {'

     

    when HTTP_REQUEST {

     

    if {[HTTP::uri] starts_with "/timesheets"} {

     

    HTTP::redirect "http://[HTTP::host]/GroupServer/en" } elseif {[HTTP::uri] starts_with "/GroupServer/en"} {

     

    pool timesheets_http_pool } elseif {[HTTP::uri] eq "/"} {

     

    HTTP::uri "/primaveraweb"} elseif {[HTTP::uri] starts_with "/primaveraweb"} {

     

    pool primaveraweb_http_pool }

     

    }

     

    '}

     

     

    Am I missing something or is there a better way to accomplish this?

     

     

    Regards,

     

    Shridhar

     

  • Hi Shridhar,

     

     

    When you test to /timesheets and to / what do you see in the browser? What do you see in the /var/log/ltm log file and the server access logs? You should see requests for /timesheets rewritten to /GroupServer/en and sent to the first pool. Requests for / should get sent to the second pool and be rewritten to /primaveraweb.

     

     

    You're correct that the snippet of code you quoted will select the second pool. Then there is a check for a request to /. Such a request will be rewritten to /primaveraweb:

     

     

     
             Use default HTTP pool  
            pool default_http_pool  
      
            log local0. "[IP::client_addr]:[TCP::client_port]: Using default_http_pool"  
      
             Rewrite path if path is exactly /timesheets  
            if {[HTTP::path eq "/"}{  
      
                Rewrite path  
               HTTP::path "/primaveraweb"  
               log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to /primaveraweb"  
            }  
     

     

     

    Aaron
  • Hi Shridhar,

    What do the logs show when you make a request to abc.com/ and abc.com/timesheets?

    You are close on your summary. But there are a few points:

    If I typed http://abc.com/timesheets, the Big-IP would first select the pool 'timesheets_http_pool' & try to look into http://server2:40702/timesheets, which is NOT present on the server. Coming to the next condition, since even the second 'if' statement also holds good, the HTTP::path would be changed to "/GroupServer/en" and thats it, the Big-IP is NOT going to again look into the pool for http://server2:40702/GroupServer/en.

    LTM is only checking the request details from the client--not checking anything in the server response or what may or may not exist on the server(s). So for a request to abc.com/timesheets, the timesheet_http_pool would be used. If the requested path was exactly /timesheets, the path will be rewritten to /GroupServer/en. Do you need to rewrite the path for other requests which start with /timesheets but aren't exactly "/timesheets"? If so, do you need to preserve part of the requested path in the rewritten path? Maybe /timesheets/anything gets rewritten to /GroupServer/en? If so, you can replace this in the iRule:

     
     if {[HTTP::path] eq "/timesheets"}{ 
          Rewrite path 
         HTTP::path "/GroupServer/en" 
         log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to /GroupServer/en" 
     }  
     

    with this:

     
      Rewrite path mapping /timesheets to /GroupServer/en 
     HTTP::path [string map {/timesheets /GroupServer/en} [HTTP::path]] 
     log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to [string map {/timesheets /GroupServer/en} [HTTP::path]]" 
     

    Suppose I typed http://abc.com/Shridhar, the Big-IP would firstly choose the default_http_pool and will try to look for http://server1:30945/Shridhar.

    The next 'if' statement would get executed only if I have typed http://abc.com/.

    Exactly correct.

    OK....I type http://abc.com/ in the browser now.

    The Big-IP selects the default_http_pool and tries to look into http://server1:30945/ and will not find any data (because the data exists in http://server1:30945/primaveraweb).

    The next 'if' statement will also get executed because I only typed http://abc.com/ this time. But the action now taken is to only change the HTTP path from '/' to '/primaveraweb' and thats it. The Big-IP again is NOT gonna select the default_http_pool and look into http://server1:30945/primaveraweb as that part is already executed.

    Both the pool selection and the path rewrite are done, so a request for http://abc.com/ will get sent to the default pool and because the requested path was / it will be rewritten to /primavera.

    Aaron
  • Thanks for making me understand the iRule execution process, Aaron. The issue got resolved. I had to make a change in your iRule to get it working.

     

     

    Here are the logs before I made those changes to your iRule -

     

     

    Aug 26 11:41:42 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1252: New GET request to abc.com/timesheets

     

    Aug 26 11:41:44 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1253: Using timesheets_http_pool

     

    Aug 26 11:41:42 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1252: Matched /timesheets check

     

    Aug 26 11:41:42 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1252: Rewriting path to /GroupServer/en

     

    Aug 26 11:41:44 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1253: New GET request to abc.com/GroupServer/en/

     

    Aug 26 11:41:44 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1253: Using default_http_pool

     

    Aug 26 11:42:31 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: New GET request to abc.com/

     

    Aug 26 11:42:31 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: Using default_http_pool

     

    Aug 26 11:42:31 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: Rewriting path to /primaveraweb

     

    Aug 26 11:42:32 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: New GET request to abc.com/primaveraweb/

     

    Aug 26 11:42:32 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: Using default_http_pool

     

    Aug 26 11:42:36 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: New GET request to abc.com/primaveraweb/action/login

     

    Aug 26 11:42:36 tmm tmm[2091]: Rule abc_com_rule : 141.144.152.122:1254: Using default_http_pool

     

     

    Notice that after the first rewrite (line 4), the Big-IP made the client to send abc.com/GroupServer/en/. Again the Big-IP checks the iRule from the beginning. This time the condition 'if {[HTTP::path] starts_with "/timesheets"}' fails and hence it was choosing the default_http_pool.

     

     

    I made the following change and that took care of it -

     

     

    if {[HTTP::path] starts_with "/timesheets" or [HTTP::path] starts_with "/GroupServer"}{

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Matched /timesheets check"

     

    pool timesheets_http_pool

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Using timesheets_http_pool"

     

    Rewrite path if path is exactly /timesheets

     

    if {[HTTP::path] eq "/timesheets"}{

     

    Rewrite path

     

    HTTP::path "/GroupServer/en"

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Rewriting path to /GroupServer/en"

     

    }

     

    }

     

     

    Thanks again for your valuable input.

     

     

    Regards,

     

    Shridhar
  • Ah, so you want requests for /timesheets or /GroupServer to go to the /timesheets pool. Nice work in tracing this and updating the iRule.

     

     

    Aaron