Forum Discussion

Jules_Green_252's avatar
Jules_Green_252
Icon for Nimbostratus rankNimbostratus
Mar 18, 2016

I want to combine 3 iRules that are all redirects without "too many redirects" error

First iRule on port 80 VIP *forces ssl unless specific uri which will remain on 80":

 

when HTTP_REQUEST { if { ! ( [string tolower [HTTP::uri]] starts_with "/investors" ) } { HTTP::redirect "https://[HTTP::host][HTTP::uri]" }

 

}

Second iRule on port 443 VIP "ssl is already enforced, but specific url will switch back to 80": (reversing the 1st iRule essentially)

 

when HTTP_REQUEST { if { ( [string tolower [HTTP::uri]] starts_with "/investors" ) } { HTTP::redirect "http://[HTTP::host][HTTP::uri]" }

 

}

Third iRule on both VIPS (forces specific host to prepend the some requests do not need the

 

when HTTP_REQUEST { if { ([HTTP::host] equals "domain.com") } { HTTP::redirect "http://www.domian.com[HTTP::uri]" } }

 

Is there a way to combine these 3 to not conflict and to have on only one VIP, so I can force everything to SSL unless there is a specific uri and if the request is for domain.com. it will add the www. and still enforce the other rules?

 

5 Replies

  • Hello,

    You can use the switch command within a single irule :

    switch -glob [string tolower [HTTP::path]] {
          "/uri/for/pool1/*" -
          "*pool_one*" -
          "/another/uri/*" {
             log local0. "Matched pool 1 paths for [HTTP::uri]"
             pool pool1
          }
          "/uri/for/pool2/*" {
             log local0. "Matched pool 2 paths for [HTTP::uri]"
             pool pool2
          }
          default {
             log local0. "Hit default for [HTTP::uri]"
             pool pool_default
          }
       }
    

    And you can check if the irule is triggered within an https or http VS using the following condition :

    if { [PROFILE::exists clientssl] == 0 }

  • Hello,

    You can use the switch command within a single irule :

    switch -glob [string tolower [HTTP::path]] {
          "/uri/for/pool1/*" -
          "*pool_one*" -
          "/another/uri/*" {
             log local0. "Matched pool 1 paths for [HTTP::uri]"
             pool pool1
          }
          "/uri/for/pool2/*" {
             log local0. "Matched pool 2 paths for [HTTP::uri]"
             pool pool2
          }
          default {
             log local0. "Hit default for [HTTP::uri]"
             pool pool_default
          }
       }
    

    And you can check if the irule is triggered within an https or http VS using the following condition :

    if { [PROFILE::exists clientssl] == 0 }

  • Here is an example of how I would run through this issue:

    when CLIENT_ACCEPTED {
    switch [TCP::local_port] {
    "443" {
    set proto "https"
    }
    default {
    set proto "http"
    }
    }
    }
    when HTTP_REQUEST {
    switch -glob [HTTP::uri] {
    "/investors*" {
    if { ($proto equals "https") } {
    HTTP::redirect "http://[HTTP::host][HTTP::uri]"
    }
    }
    default {
    if { ($proto equals "http") } {
    HTTP::redirect "https://[HTTP::host][HTTP::uri]"
    } elseif { ([HTTP::host] equals "domain.com") } {
    HTTP::redirect "$proto://www.domain.com[HTTP::uri]"
    }
    }
    }
    }
    

    The basic concept is - you can have multiple HTTP::redirect commands in a single iRule, but no two can be logically reachable at the same time. So long as the logic only allows one to execute in any given request, you should be clear. Switch and elseif's eliminate the potential for multiple executions.