Forum Discussion

Shlairshe_84486's avatar
Shlairshe_84486
Icon for Nimbostratus rankNimbostratus
Apr 25, 2014

url redirect with rewrite capability

This is what should happen, when a user types http://bearcub.dev.leo.world.com/lookout the resulting website should be http://lion.dev.leo.world.com/lookout.

 

but the client wants the resulting url of lion.dev.leo.world.com/lookout to show as http://bearcub.dev.leo.world.com/lookout.

 

so in effect, the url in the face of the user DOES not change, it still remains the same as the url typed initially by the user which in this case is http://bearcub.dev.leo.world.com/lookout. The final page in the browser page should still have the initial typed url of http://bearcub.dev.leo.world.com/lookout

 

This Code works, but it does not get me the result of the final url not changing in the browser page.

 

when HTTP_REQUEST {

 

if {[string tolower [HTTP::host]] equals "bearcub.dev.leo.world.com" and [string tolower [HTTP::uri]] equals "/lookout" } { HTTP::redirect "http://lion.dev.leo.world.com/lookout" HTTP::header replace Host "bearcub.dev.leo.world.com"

 

} 

}

 

9 Replies

  • Assuming that the page is on the same server all you'd need is to change the uri before passing it forward:

    when HTTP_REQUEST {
    
        set host [string tolower [HTTP::host]]
        set uri [string tolower [HTTP::uri]]
    
        if { $host equals "lion.dev.leo.world.com" and $uri equals "/lookout" } { 
            HTTP::header replace Host "bearcub.dev.leo.world.com"
        }
    }
    

    Now, if there's any images, stylesheets ets below /lookout that needs to be loaded you might be better off by using this:

    when HTTP_REQUEST {
    
        set host [string tolower [HTTP::host]]
        set uri [string tolower [HTTP::uri]]
    
        if { $host equals "lion.dev.leo.world.com" and $uri starts_with "/lookout" }     { 
            HTTP::header replace Host "bearcub.dev.leo.world.com"
        }
    }
    

    If the other bearcub.dev.leo.world.com resides on another server you will want to add a pool decision as well:

    when HTTP_REQUEST {
    
        set host [string tolower [HTTP::host]]
        set uri [string tolower [HTTP::uri]]
    
        if { $host equals "lion.dev.leo.world.com" and $uri starts_with "/lookout" } { 
            HTTP::header replace Host "bearcub.dev.leo.world.com"
            pool bearcub_pool
        }
    }
    

    /Patrik

  • Some questions:

    1. Is lion.dev.leo.world.com hosted on the same servers as bearcub.dev.leo.world.com?
    2. I assume you separate requests by host header?
    3. Can you see anything in the IIS logs?

    Try this one and see if you see anything in the /var/log/ltm log (replace the pool with the pool for bearcub.dev.leo.world.com).

    when HTTP_REQUEST {
    
        set host [string tolower [HTTP::host]]
        set uri [string tolower [HTTP::uri]]
    
        if { $host equals "lion.dev.leo.world.com" and $uri starts_with "/lookout" } { 
            HTTP::header replace Host "bearcub.dev.leo.world.com"
            pool bearcub_pool
            log local0. "Sending to the bearcub pool"
        }
    }
    
  • Hi!

    I think I understood your request.

    The reason why the location in the client browser changes is that you keep adding a HTTP::redirect to the iRules. An HTTP redirect would send a response to the client asking it to get the content from another domain/uri, and as you said, this is not what you want.

    If you are using the same pool for lion and bearcub I assume that you're using host headers to separate requests to the two different sites and thus you need to replace the host if you want the request to end up at another site than the original request:

    Let's look at the rule again and I'll explain each step with comments:

    The rule will be executed whenever there is an HTTP request
    when HTTP_REQUEST {
    
        Saving the host header and the URI to variables 
        set host [string tolower [HTTP::host]]
        set uri [string tolower [HTTP::uri]]
    
        Comparing the host header and the URI to know when to rewrite the host header
        In this case it would only trigger if the client uses lion.dev.leo.world.com
        and the uri starts with /lookout.
        That would include uris like /lookout, /lookout/index.aspx, /lookout/style.css etc.
    
        if { $host equals "lion.dev.leo.world.com" and $uri starts_with "/lookout" } {
            Replaces the host header in the packet with bearcub.dev.leo.world.com
            By replacing the host header with bearcub.dev.leo.world.com the request would
            be sent to the bearcub site
            HTTP::header replace Host "bearcub.dev.leo.world.com"
    
            Logging any requests matching the conditions above
            log local0. "Sending to the bearcub pool because of host: $host and uri: $uri"
        }
    }
    

    This would mean that the load balancer would replace the host header for all requests destined for lion.dev.leo.world.com with an uri that starts with /lookout. It would do this before sending the request on to the server.

    Note that if /lookout includes any other objects that does not reside under /lookout (ie "/styles/style.css") they would not go to bearcubs, but to lions.

    /Patrik

  • Now you have totally lost me. :)

     

    You want http://bearcub.dev.leo.world.com/lookout to show the content of http://lion.dev.leo.world.com/lookout, but you don't want the browser location bar to change. Am I right?

     

    But now you say that you don't want to fetch any content from the site bearcub.dev.leo.world.com?

     

    In order to prevent the location from changing you need to rewrite the request in the load balancers to match another site on the server side. The only other options would be to do a redirect (which always changes the browser location bar), or actually host the content you want on the server.

     

    Please note that replacing the hosts header is not the same as changing the location bar in the browser. The hosts header is a header that's basically only used by the server, ie for choosing which site the request should go to. When changing the hosts header for incoming requests the client would never notice the change, except for the fact that they would get different content.

     

    Check out this article for a better explanation:

     

    http://www.it-notebook.org/iis/article/understanding_host_headers.htm

     

    /Patrik

     

  • i think it may be useful if you run tcpdump on bigip and see how request and response look like.

    if you are running 11.2.0 or later, you can use p interface modifier to capture both clientside and serverside packet.

     tcpdump -nni 0.0:nnnp -s0 -w /var/tmp/output.pcap host x.x.x.x -v
    x.x.x.x is client ip
    

    sol13637: Capturing internal TMM information with tcpdump

    http://support.f5.com/kb/en-us/solutions/public/13000/600/sol13637.html
    • Shlairshe_84486's avatar
      Shlairshe_84486
      Icon for Nimbostratus rankNimbostratus
      Patrick, The following irule worked, I included the header replace statement, just before the pool associated with the server servicing both sites and it worked. when HTTP_REQUEST { if { ([HTTP::uri] starts_with "/arcgis") } { HTTP::header replace Host "gis.dev.geo.census.gov" pool arcgis_tigerweb.dev.geo_80_pool } Thanks for the leads, I would not have thought to use a header replacement in this case, my thoughts were far from that.
  • i think it may be useful if you run tcpdump on bigip and see how request and response look like.

    if you are running 11.2.0 or later, you can use p interface modifier to capture both clientside and serverside packet.

     tcpdump -nni 0.0:nnnp -s0 -w /var/tmp/output.pcap host x.x.x.x -v
    x.x.x.x is client ip
    

    sol13637: Capturing internal TMM information with tcpdump

    http://support.f5.com/kb/en-us/solutions/public/13000/600/sol13637.html
    • Shlairshe_84486's avatar
      Shlairshe_84486
      Icon for Nimbostratus rankNimbostratus
      Patrick, The following irule worked, I included the header replace statement, just before the pool associated with the server servicing both sites and it worked. when HTTP_REQUEST { if { ([HTTP::uri] starts_with "/arcgis") } { HTTP::header replace Host "gis.dev.geo.census.gov" pool arcgis_tigerweb.dev.geo_80_pool } Thanks for the leads, I would not have thought to use a header replacement in this case, my thoughts were far from that.
  • Patrick,

     

    The following irule worked, I included the header replace statement, just before the pool associated with the server servicing both sites and it worked.

     

    when HTTP_REQUEST { if { ([HTTP::uri] starts_with "/arcgis") } { HTTP::header replace Host "gis.dev.geo.census.gov" pool arcgis_tigerweb.dev.geo_80_pool }

     

    Thanks for the leads, I would not have thought to use a header replacement in this case, my thoughts were far from that.