Forum Discussion

Bruce_Walker_11's avatar
Bruce_Walker_11
Icon for Nimbostratus rankNimbostratus
Jun 22, 2010

iRule for taking part of an original URI and inserting to a new URL

Hi there,

 

 

Was wondering what an iRule would look like that does the following:

 

 

Original URL:

 

 

Required URL: http://www.environment.domain/globalSearch?q=someuritocopy

 

 

The URI past the = could be of varying length.

 

 

Thanks,

 

 

Bruce

 

 

8 Replies

  • Hi Bruce,

    You can parse the value for a URI parameter using a slight change to URI::query:

    URI::query "?&[HTTP::query] &param_name

    So to parse the value of the Ntt parameter and use it in a URI rewrite, you can do something like this:

    when HTTP_REQUEST {
        Check if some condition is true?
       if { [string tolower [HTTP::host]] eq "search.environment.domain" and [HTTP::path] eq "/listing" and [HTTP::query] contains "Ntt"}{
           Rewrite the URI with the original path and the query string replaced 
             with just the Ntt parameter value set for the q parameter
          HTTP::uri "/globalSearch?q=[URI::query "?&[HTTP::query] &Ntt]"
           Update the host header
          HTTP::header replace Host "www.environment.domain"
       }
    }

    Aaron
  • Hi Aaron,

    Thanks for the above, but it looks like the URI is not being rewritten. The rule is being matched and the host header is changed, but the URI remains the same as original.

    This is the request: (which the output URI should change to

    Your modified iRule is below with the logging statements in I am using.

     
    when HTTP_REQUEST { 
     Check if some condition is true? 
    if { [string tolower [HTTP::host]] eq "search.devint.lpo" and [HTTP::path] eq "/listing" and [HTTP::query] contains "Ntt"} 
    {  Log the original Host and URI request 
    log local0. "Original Client Request is: [HTTP::header value host][HTTP::uri]" 
     Rewrite the URI with the original path and the query string replaced 
     with just the Ntt parameter value set for the q parameter 
    HTTP::uri "/globalSearch?q=[URI::query "?&[HTTP::query] &Ntt"]" 
     Update the host header 
    HTTP::header replace Host "www.devint.lpo" 
     Log the modified Host and URI 
    log local0. "Modified Client Request is: [HTTP::header value Host][HTTP::uri]" 
    }
     }

    LTM Log output:

    tmm tmm[1817]: Rule searchrewrite.iRule.devint : Original Client Request is: search.devint.lpo/listing?Ntt=test

    tmm tmm[1817]: Rule searchrewrite.iRule.devint : Modified Client Request is: www.devint.lpo/listing?Ntt=test

    Any thoughts?

    Thanks,

    Bruce

  • Hi Bruce,

    The values for most HTTP:: commands are cached in the same event of the same priority. To log the updated value, you can add a second HTTP_REQUEST event which runs after the default priority of 500:

    when HTTP_REQUEST { 
        Check if some condition is true? 
       if { [string tolower [HTTP::host]] eq "search.devint.lpo" and [HTTP::path] eq "/listing" and [HTTP::query] contains "Ntt"} {
           Log the original Host and URI request 
          log local0. "Original Client Request is: [HTTP::header value host][HTTP::uri]" 
    
           Rewrite the URI with the original path and the query string replaced 
           with just the Ntt parameter value set for the q parameter 
          HTTP::uri "/globalSearch?q=[URI::query "?&[HTTP::query] &Ntt"]" 
    
           Update the host header 
          HTTP::header replace Host "www.devint.lpo" 
    
       }
    }
    when HTTP_REQUEST priority 501 {
        Log the modified Host and URI 
       log local0. "(501) Modified Client Request is: [HTTP::header value Host][HTTP::uri]" 
    }
    

    Aaron
  • Aaron,

    Wrong Host? You want to change the URL host and not the Host header.

    when HTTP_REQUEST { 
     if it matches the request replace the request with a new one passing the old parameter.
      if { "[HTTP::host]/[HTTP::path]?[HTTP::query]" starts_with "search.devint.lpo/listing?Ntt=" } {
        HTTP::host "www.devint.lpo"
        HTTP::uri [concat "/globalSearch?q=" [URI::query "?[HTTP::query]" "Ntt"]]
      }
    }
    when HTTP_REQUEST priority 501 {
    ...as above...
    }
    

    Syntax of the 5th line needs to be verified. Ill test it shortly and report back if there is any issues.

    Regards

    Kevin
  • Hi Kevin,

     

     

    The forum software double HTML encodes &'s in code blocks and so they were displaying as & amp ; (without the spaces). I've edited that now. Can you retry the updated version above?

     

     

    Aaron
  • Hi Kev,

     

     

    By default most HTTP user agents don't use fully qualified URLs in the URI field. So you can just replace the HTTP host header using 'HTTP::header replace Host "newhost.example.com". If a user agent did include the host in a fully qualified URL in the URI, the server must ignore the host header. In that case, you'd want to replace the host portion in the URI. However, the only times I've seen clients doing this is when they're using a web proxy. Most web proxies convert the URI to a local reference when sending the requests on.

     

     

    Also, HTTP::host only allows you to retrieve the host header value--not set it.

     

     

    Aaron