Forum Discussion

Nicola_DT's avatar
Nicola_DT
Icon for Nimbostratus rankNimbostratus
Aug 20, 2009

irule for rewriting an uri in an http request

Hi everyone,

 

I am writing a simple irule so that if an http request will arrive on the virtual with an uri that starts with "/config" the request will be passed to the pool rewrited and the url "/config" must be replaced by "/main".

 

 

 

The irule 'should' work:

 

 

 

when HTTP_REQUEST {

 

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

 

set HTTP::uri /main

 

}

 

}

 

 

 

 

Issus is I do not know if the Bigip has to re-substitute the uri in the response to the client, for that I'd add something like:

 

when HTTP_RESPONSE

 

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

 

set HTTP::uri /config}

 

}

 

 

 

But this second part of the irule gives me errors:

 

 

01070151:3: Rule [aaa] error:

 

line 1: [wrong args] [when HTTP_RESPONSE ]

 

line 3: [command is not valid in the current scope] [if { [HTTP::uri] starts_with "/main" } {

 

set HTTP::uri /config} ]

 

line 7: [command is not valid in the current scope] [}]

 

 

 

Any Tip on how to fix this easy uri rewriting issue ?

 

 

Thanx,

 

Nicola.

7 Replies

  • I think the first irule event was more correct, but needs a monitor tweak.

     
     when HTTP_REQUEST { 
      if {[HTTP::uri] starts_with "/config"} { 
         HTTP::uri /main 
         } 
     } 
     

    You don't need the response unless you want to change the response towards the client.

    Another way is a redirect

     
     when HTTP_REQUEST { 
      if {[HTTP::uri] starts_with "/config"} { 
         HTTP::redirect http://[HTTP::host]/main 
         } 
     } 
     

    Hope this helps

    CB

  • The "HTTP::uri" is a command with muliple purposes. If you don't supply a parameter, it retrieves the value. If you give it a uri, then it will set the value. You need to remove your "set" command like this:

     

     

     when HTTP_REQUEST { 
       if { [HTTP::uri] starts_with "/config"} { 
         HTTP::uri /main 
       } 
     }

     

     

    This code will keep the URI intact in the clients browser but change it before it gets to the server.

     

     

    If you want the browser to stay the same (ie /config) then you should be alls et.

     

     

    If you want to change the browser, then there's a problem with this approach. The URI is part of the request, not the response. The browser displays the URI that was sent to the server in the initial request. If you want to change the browser, then you'll want to issue a redirect to the client. This will essentially tell the client (browser) to issue a new request to the updated URI.

     

     

     when HTTP_REQUEST { 
       if { [HTTP::uri] starts_with "/config" } { 
         HTTP::redirect "http://[HTTP::host]/main" 
       } 
     }

     

     

    So, hopefully that answers your questions. One last thing to keep in mind is that you are replacing "ALL" requests that start with "/config" to a URI of "/main". So http://server/config1234, http://server/config/a/b, etc. will all map to http://server/main. If you want to retain the original portion of the URI past the "/config" value, then you'll want to do some string replacement (look at the "string map" TCL command for an easy way to do it).

     

     

    Hope this helps...

     

     

    -Joe
  • Thanx for the tips,

     

     

    as a matter of fact if I try to save without the "set" It gives ma an error:

     

     

    01070151:3: Rule [Irule_riscrivi_uri] error:

     

    line 9: [undefined procedure: http::uri] [http::uri /cwmpWeb/CPEMgt]

     

     

    I am using version 9.3.1 hf 4

     

     

    Nicola.

     

  • The command names are case sensitive, so it should be HTTP::uri.

     

     

    Aaron
  • The value for HTTP::uri is cached within the same event and event priority. If you want to see the effect of the change, you can add a second HTTP_REQUEST event that runs after your change is made with a log statement. Once you're okay with the test, you can comment out/remove the debug event.

     
     when HTTP_REQUEST priority 501 { 
      
        log local0. "[IP::client_addr]:[TCP::client_port] (501): \[HTTP::uri\]: [HTTP::uri]" 
     } 
     

    Aaron
  • Nice m8

     

     

    Will give it a try.

     

     

    Thanx again,

     

    Nicola.