Forum Discussion

JustCooLpOOLe's avatar
JustCooLpOOLe
Icon for Cirrocumulus rankCirrocumulus
Feb 10, 2023

iRule Shenanigans - My Brain hurts

Hola,

We have a virtual server where we host a bunch of iFiles.  We want to create an irule that redirects to a specific path if the user just puts the domain or IP address and nothing else.  That type of redirect is simple but what seems to happen is that the the iRule with the redirect, "redirects" but nothing is displayed and you get a reset.  What I want to happen is that when the iRule fires, it redirects back to the VIP and then hits the iRule with the various iFiles displayed by a switch statement.

I created a HTTP VIP so that I could redirect to the HTTPS VIP and that works but trying to combine into one.  Basically, one irule that redirects from https://mysite.com -> https://mysite.com/mysite.html then when it loops back, it hits my other iRule that says:

when HTTP_REQUEST {

    switch [HTTP::uri] {
         "/mysite.html" { HTTP::respond 200 content [ifile get "mysite.html"] }
         "/yoursite.html" { HTTP::respond 200 content [ifile get "yoursite.html"] }  

    }

}

Kind of like that but on a single HTTPS virtual server.  Any help would be greatly appreciated.

  • Paulius's avatar
    Paulius
    Feb 13, 2023

    JustCooLpOOLe I see the issue with your iRule and it's both in the if statement and switch statement. For the if statement where you look at the HTTP::host you are matching it to "/" which will never match because host names do not have a "/" in them. The issue with the switch statement is that you are not matching against any particular value denoted by "switch {" which isn't matching against anything in particular. Based on the iRule that you have in place it doesn't seem as though you are matching on a host at all and are just concerned with the URI path so the following iRule should work for you. In conjunction with this iRule you should consider configuring a OneConnect profile so that every HTTP request is passed through the iRule rather than just the initial HTTP request when the TCP connection is formed. I would also like to note that the iRule that you provided does not match what you put in your original post so if what I have provided this time doesn't meet your needs could you provide additional information on what you are attempting to achieve?

    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::host]
        set URI [string tolower [HTTP::uri]]
    
        switch -glob -- ${URI} {
            "/" {
                HTTP::redirect 301 Location "https://${HOST}/mainpage.html"
            }
            "/mainpage.html" {
                HTTP::respond 200 content [ifile get "mainpage.html"]
            }
            "/mylogo.jpg" {
                HTTP::respond 200 content [ifile get "mylogo.html"]
            }
            default {
                drop
            }
        }
    
    }

     

  • JustCooLpOOLe Based on the information you provided I believe this might be the all in one that you're looking for. Please keep in mind that I have assumed that if it's the domain with just "/" as the path you want to perform a redirect otherwise you just want to send them to the default pool. I have also assumed that you have a default pool configured on the virtual server as well.

    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        set HOST [HTTP::host]
        set URI [string tolower [HTTP::uri]]
    
        switch -glob -- ${HOST} {
            "mysite.com" {
                if { ${URI} == "/" } {
                    HTTP::respond 301 Location "https://${HOST}/mysite.html"
                } elseif { ${URI} == "/mysite.html" } {
                    HTTP::respond 200 content [ifile get "mysite.html"]
                } else {
                    pool ${DEFAULT_POOL}
                }
            }
            "yoursite.com" {
                if { ${URI} == "/" } {
                    HTTP::respond 301 Location "https://${HOST}/yoursite.html"
                } elseif { ${URI} == "/yoursite.html" } {
                    HTTP::respond 200 content [ifile get "yoursite.html"]
                } else {
                    pool ${DEFAULT_POOL}
                }
            } 
            default {
                pool ${DEFAULT_POOL}
            }
        }
    
    }
    • JustCooLpOOLe's avatar
      JustCooLpOOLe
      Icon for Cirrocumulus rankCirrocumulus

      Thanks!  So there are no default pools because everything is provided by an iFile.  It's really one main page (iFile) that calls multiple other iFiles for like logos and links to other pages.  So the the problem is that we tried to do put the if statement before the switch but since it's on the same virtual server, it doesn't appear to redirect.  Like so:  

       

      when HTTP_REQUEST {
      
           if { HTTP::host eq "/" } { HTTP::redirect https://[HTTP::host]/mainpage.html }
      
           switch {
      
                "/mainpage.html" { HTTP::respond 200 content [ifile get mainpage.html] }
                "/mylogo.jpg" { HTTP::respond 200 content [ifile get mylogo.html] }
                ...
      
           }
      
      
      }

       

      Not sure if that makes sense.

      • Paulius's avatar
        Paulius
        Icon for MVP rankMVP

        JustCooLpOOLe I see the issue with your iRule and it's both in the if statement and switch statement. For the if statement where you look at the HTTP::host you are matching it to "/" which will never match because host names do not have a "/" in them. The issue with the switch statement is that you are not matching against any particular value denoted by "switch {" which isn't matching against anything in particular. Based on the iRule that you have in place it doesn't seem as though you are matching on a host at all and are just concerned with the URI path so the following iRule should work for you. In conjunction with this iRule you should consider configuring a OneConnect profile so that every HTTP request is passed through the iRule rather than just the initial HTTP request when the TCP connection is formed. I would also like to note that the iRule that you provided does not match what you put in your original post so if what I have provided this time doesn't meet your needs could you provide additional information on what you are attempting to achieve?

        when HTTP_REQUEST priority 500 {
        
            set HOST [HTTP::host]
            set URI [string tolower [HTTP::uri]]
        
            switch -glob -- ${URI} {
                "/" {
                    HTTP::redirect 301 Location "https://${HOST}/mainpage.html"
                }
                "/mainpage.html" {
                    HTTP::respond 200 content [ifile get "mainpage.html"]
                }
                "/mylogo.jpg" {
                    HTTP::respond 200 content [ifile get "mylogo.html"]
                }
                default {
                    drop
                }
            }
        
        }