Forum Discussion

johns's avatar
johns
Icon for Employee rankEmployee
Jul 28, 2005

Using URI to rewrite host

I am trying to come up with a rule where the first directory name of the uri is used to rewrite the URL. an example will be:

 

 

http://www.foo.com/abc/doc/index.html =>

 

http://abc.foo.com/abc/doc/index.html.

 

 

I want to make it so that the rule is general enough to be applied to multiple sites like this. I am thinking I will probably have to use regex to parse up to the second "/" after the URL and store that in a variable, then constrcut URL from that. Is that possible?

 

 

Thanks.

25 Replies

  • Below is my rule, and for HTTP, it is close to working as expected, but for HTTPS via SSL proxy, I am noticing strange behavior. Please see the ltm log snippet from the 2 at the bottom. For some reason, it will attach the "token" twice in front of the host when going via SSL proxy. Any idea why, would this be a bug? I had both VIP configured identically except for the proxy part, using the same rule and pool.

    
    when HTTP_REQUEST {
        set host [HTTP::host]
       log local0. $host
        set uri [HTTP::uri]
        set token [getfield [HTTP::uri] "/" 2] 
        if { $token eq "" } {
          log local0. "no path specified so ignore"
        } else {
          if { [matchclass $uri ends_with $::file_extensions] > 0 } {
            log local0. "Found file request, leave as is!"
            set host "$token.$host"
            HTTP::header replace "host" $host
          } else {
            log local0. "Not a file request, update host and check for trailing slash "
            if { not ( $host starts_with $token ) } {
              set host "$token.$host"
              log local0. "Updated host with token: $host"
              HTTP::header replace "Host" $host
            }
            if { $uri ends_with "/" } {
              log local0. "Uri ends with a slash, all's good"
            } else {
              log local0. "Uri doesn't end with a slash, appending one"
              append uri "/"
              HTTP::uri $uri
            }
          }
        }
        log local0. "host: $host"
        log local0. "uri : $uri"
      }

    Log from HTTP LB:

    Thu Aug 11 02:14:34 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Not a file request, update host and check for trailing slash

    Thu Aug 11 02:14:34 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Updated host with token: aao.cc71.ddc-f5.com

    Thu Aug 11 02:14:34 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Uri doesn't end with a slash, appending one

    Thu Aug 11 02:14:34 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: aao.cc71.ddc-f5.com

    Thu Aug 11 02:14:34 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /aao/

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: dmb_i.gif.cc71.ddc-f5.com

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /dmb_i.gif

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: dmb_m.gif.cc71.ddc-f5.com

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /dmb_m.gif

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: AAO.cc71.ddc-f5.com

    Thu Aug 11 02:14:35 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /AAO/_images/banner_checkbox1.gif

    Log from HTTPS via SSL proxy:

    Thu Aug 11 02:31:00 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Not a file request, update host and check for trailing slash

    Thu Aug 11 02:31:00 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Uri doesn't end with a slash, appending one

    Thu Aug 11 02:31:00 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: aao.cc71.ddc-f5.com

    Thu Aug 11 02:31:00 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /aao/

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: dmb_i.gif.dmb_i.gif.cc71.ddc-f5.com

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /dmb_i.gif

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: dmb_m.gif.dmb_m.gif.cc71.ddc-f5.com

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /dmb_m.gif

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : Found file request, leave as is!

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: AAO.AAO.cc71.ddc-f5.com

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /AAO/_images/banner_checkbox1.gif

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Hmm, about all I can say, is that you have a section of code that is not checking whether the host already contains the token and adding it anyway. Since it seems you always want this in the host, I would hoist that logic to before the check for a image file:

     

    
    when HTTP_REQUEST {
        set host [HTTP::host]
       log local0. $host
        set uri [HTTP::uri]
        set token [getfield [HTTP::uri] "/" 2] 
        if { $token eq "" } {
          log local0. "no path specified so ignore"
        } else {
          if { not ( $host starts_with $token ) } {
            set host "$token.$host"
            log local0. "Updated host with token: $host"
            HTTP::header replace "Host" $host
          }
          if { [matchclass $uri ends_with $::file_extensions] > 0 } {
            log local0. "Found file request, leave as is!"
          } else {
            log local0. "Not a file request, update host and check for trailing slash "
            if { $uri ends_with "/" } {
              log local0. "Uri ends with a slash, all's good"
            } else {
              log local0. "Uri doesn't end with a slash, appending one"
              append uri "/"
              HTTP::uri $uri
            }
          }
        }
        log local0. "host: $host"
        log local0. "uri : $uri"
      }

     

  • The onyl thing I am really struglling with now is that when I type in the trailing slash, the page displays propery, but if not, then the menu and login buttons do not work. When I look at the log, below entry is the one that is associated with the menu display which is not being processed as I expect it to...........

     

     

     

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : host: dmb_i.gif.cc71.ddc-f5.com

     

    Thu Aug 11 02:31:01 EDT 2005 tmm tmm[739] Rule host_rewrite2 : uri : /dmb_i.gif
  • One more try. I've tried to simplify the logic in your code and based off of your requirements:

     

     

    www.site.com/dir1 => dir1.www.site.com/dir1/

     

    www.site.com/dir1/file.htm => www.site.com/dir1/file.htm

     

    www.site.com/dir2/ => dir2.www.site.com/dir2/

     

     

    this code should work:

     

     

    when HTTP_REQUEST {
      set host [HTTP::host]
      set uri [HTTP::uri]
      set token [getfield [HTTP::uri] "/" 2]
       If no uri is passed in, then leave everything as is
      if { $token ne "" } {
        if { [matchclass $uri ends_with $::file_extensions] > 0 } {
           for case www.site.com/dir1/file.htm => www.site.com/dir1/file.htm
          log local0. "Found file request, leaving host and uri alone"
        } else {
          log local0. "Not a file request, update host and check for trailing slash "
           Check if host starts with token
           If not, then prepend it with the token
          if { ! ($host starts_with $token) } {
             ie. www.site.com/dir1 => dir1.www.site.com/dir1
            log local0. "Host doesn't start with token so updating host"
            set host "$token.$host"
            HTTP::header replace "Host" $host
          }
           Check if url ends with a slash
           if not, then append it with one
          if { ! ($uri ends_with "/") } {
             ie. dir1.www.site.com/dir1 => dir1.www.site.com/dir1/
            log local0. "Uri doesn't end with a slash, updating"
            append uri "/"
            HTTP::uri $uri
          }
        }
      }
      log local0. "host: $host"
      log local0. "uri : $uri"
      log local0. "full: $host$uri"
    }

     

     

    -Joe
  • Sorry, mistake on my part on what we are trying to do:

     

     

     

    cc71.ddc.com/app1 -> app1.cc71.ddc.com/app1/

     

    cc71.ddc.com/app1/ -> app1.cc71.ddc.com/app1/

     

    cc71.ddc.com/app1/file.extension -> app1.cc71.ddc.com/app1/file.extension

     

    app1.cc71.ddc.com/app1/ -> no change.

     

    app1.cc71.ddc.com/app1/file.extension -> no change.

     

     

    Also found in the server return that some of the objects are referenced by file name only, so the request is coming from the client as:

     

    cc71.ddc.com/file.extension and now we have to turn that into the same format of app1.cc71.ddc.com/app1/file.extension.

     

     

    At this point, I am wondering if I will have to have rule for each and every app separately instead of trying to use a generic rule to cover all apps (paths)