For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

johns's avatar
johns
Ret. Employee
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

  • johns's avatar
    johns
    Ret. Employee
    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"
      }

     

  • johns's avatar
    johns
    Ret. Employee
    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
  • johns's avatar
    johns
    Ret. Employee
    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)