Forum Discussion

Steve_Manuel_11's avatar
Steve_Manuel_11
Icon for Nimbostratus rankNimbostratus
Oct 06, 2006

http/https redirect

Hello everyone;

 

 

I'm trying to do a simple http https redirect for a VSA.

 

 

Before

 

 

http://cms-d3.tmi.telus.com

 

 

looking to see

 

 

https://cms-d3.tmi.telus.com

 

 

I found the code sample

 

 

when HTTP_REQUEST {

 

HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]

 

}

 

 

and created an iRule called HTTP_HTTPS_REDIRECT. I attached this iRule to the VSA

 

 

My ultimate end state is to add the this functionality to my URI parse rule

 

 

RULE NAME: D3_INT1_CMS_SECURE_REDIRECT

 

VERSION : 1.0

 

DESC : CMS (Documentum) Secure Redirects

 

 

when HTTP_REQUEST {

 

set uri [HTTP::uri]

 

 

Extract first element after slash in URIset

 

set target [getfield [HTTP::uri] "/" 2]

 

To perform redirect

 

Check if the field doesn't contain a dot

 

Check if the uri doesn't contain the field followed by a slash

 

Check if http request and redirect to https

 

 

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

 

pool D3_INT1_CMS

 

}

 

elseif { [HTTP::uri] starts_with "/webtop/" } {

 

pool D3_INT1_CMS

 

}

 

elseif { [HTTP::uri] starts_with "/woh/" } {

 

pool D3_INT1_CMS

 

}

 

elseif { [HTTP::uri] starts_with "/wp/" } {

 

pool D3_INT1_CMS

 

}

 

elseif { not ( $target contains ".") and not ([HTTP::uri] contains "${target}/") } {

 

HTTP::redirect "https://[HTTP::host]/${target}/"

 

}

 

elseif { [HTTP::uri] starts_with "http://cms" } {

 

HTTP::redirect "https://cms-d3.tmi.telus.com"

 

}

 

else { pool D3_INT1_CONTENT

 

}

 

}

 

 

Thx

 

Steve
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Hi Steve -

    You didn't really indicate if you were encountering dificulty, or what kind of answer you were hoping for, or what exactly the logic is you're trying to enforce, but I can see a couple of things you might want to clean up.

    1) You are setting the variable "uri" and never using it. Since the function [HTTP::uri] is cached, you could reduce the iRule overhead by not setting the variable and continuing to use [HTTP::uri]. However, you might want to consider a case-insensitive comparison, setting the variable to equal the all-lower-case version of the URI, and then refering to the variable instead of the function:
    set uri [string tolower [HTTP::uri]]
    ...
    if {$uri starts with "/da/"}{
      ...
    2) A couple of things make me wonder if you are expecting to see the protocol scheme & hostname as part of the output of [HTTP::uri]. URI means the part /after/ the hostname, including the leading slash. For example, in "http://host.domain.com/uri", the URI is "/uri", and the hostname is "host.domain.com". [HTTP::host] is the command to use for comparison with the hostname in the request.

    3) You could use a class or a switch construct to manage traffic for different URIs. Since the destination is the same, I recommend a class (data group list) containgin the URI's for which you will switch to the CMS pool. It also looks like you could extract just the first directory and use that value for most of your conditions.

    I'm not sure what you were trying to catch with the second to last elseif, but perhaps something more like this iRule:
    
    when HTTP_REQUEST {
      set uri_first [getfield [string tolower [HTTP::uri]] "/" 2]
      if {[matchclass $uri_first equals $::CMS_uris]}{
        pool D3_INT1_CMS
      } elseif { not ( $uri_first contains ".") and not ([HTTP::uri] contains "${uri_first}/") } {
        HTTP::redirect "https://[HTTP::host]/${target}/"
      } elseif {[string tolower [HTTP::host]] starts_with "cms"} {
        HTTP::redirect "https://cms-d3.tmi.telus.com"
      } else { 
        pool D3_INT1_CONTENT
      }
    }
    which would use the following class list:
    class CMS_uris {
      "da"
      "webtop"
      "woh"
      "wp"
    }

    HTH

    /deb
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Hi Steve -

     

     

    You typically would not need to check the local port in a rule like this, since virtual servers are usually port-specific (but if you needed to, you could use [TCP::local_port]). Unless you are applying the iRule to a wildcard virtual configured to support both HTTP and HTTPS, you'll have separate virtuals, one for HTTP and one for HTTPS, and all requests on each virtual would either be HTTP or HTTPS (not both). Since you are intending to redirect in some cases to the same hostname, different scheme, you will definitely need to have separate virtuals for HTTP and HTTPS to prevent an infinite redirect loop on your last 2 conditions. So you most likely would apply this iRule to the HTTP virtual only, and allow traffic on the HTTPS virtual to fall through to the CONTENT pool.

     

     

    The confusion I mentioned earlier was specifically regarding where you are checking for the "." and the trailing slash. What value are you expecting to see for the variable "target"? (Logging the value of derived variables is a primary iRule troubleshooting technique you can leverage -- "log local0. $target" will reveal the value of the variable in the LTM log.)

     

     

    It seems as if the iRule you originally created was intended to: * Honor HTTP requests for resources within the 4 listed directories and forward to the CMS pool (cleartext on both sides)

     

    * Redirect to HTTPS any request with a different first directory which doesn't contain a "." or doesn't include a trailing slash

     

    * Redirect to HTTPS any request for a hostname beginning with cms.

     

    * Honor all other HTTP requests and forward to the CONTENT pool. which sort of seems to leave some odd holes in the resulting redirection pattern -- see these sample URI's and results using my current logic:http://cms.domain.com/da/my.directory.................forward to CMS pool (because of first directory in uri)

     

    http://cms.domain.com/my.directory....................redirect to https://cms-d3.tmi.telus.com (because of hostname)

     

    http://cms.domain.com/my.directory/...................redirect to https://cms-d3.tmi.telus.com (because of hostname)

     

    http://cms.domain.com/my.directory/something_else.....redirect to https://cms-d3.tmi.telus.com (because of hostname)

     

    http://host.domain.com/my.directory...................forward to CONTENT pool (no conditions match because of "." in directory name)

     

    http://host.domain.com/myDirectory/...................forward to CONTENT pool (no conditions match because of "/" trailing directory name)

     

    http://host.domain.com/myDirectory....................redirect to https://host.domain.com/myDirectory/ (because no "." and no "/")

     

    http://host.domain.com/myDirectory/other..............forward to CONTENT pool (no conditions match because of "/" trailing directory name)

     

    http://host.domain.com/myDirectory/another............forward to CONTENT pool (no conditions match because of "/" trailing directory name)Bottom line, you may need to further clarify the traffic management goals, and I'd definitely recommend adding some logging before or within each condition to see what values are being evaluated by each condition.

     

     

    HTH

     

    /deb