Forum Discussion

Deepak_Nair's avatar
Mar 10, 2021

HTTP 404 ERROR HANDLING through IRULE

Hello Experts ,

 

I am trying to build an irule which will send a HTTP 404 error CODE if the user intentionally or mistakenly typed a wrong URL .

 

Below is the IRULE that i have written :

 

 

when HTTP_REQUEST { 
  if {([string tolower [HTTP::host]] equals "xyz.APAC.com") && [HTTP::uri] starts_with "/ARCHIAC" } {
    HTTP::uri [string map [list "/archiac/" "/arcgis/" ] [HTTP::uri]]
    pool PL_BNE_ENT_6443
    return
  } 
  if {([string tolower [HTTP::host]] equals "xyz.APAC.com") && [HTTP::uri] starts_with "/archiacportal" } {
    pool PL_BNE_ENT_arcgisportal_443
    return
  }
  if {[HTTP::uri] matches_regex ".*" } {
    HTTP::respond 404 content {Page Not Found Page Not Found} 
  } 
}

 

 

This irule work fine for most of the cases . BUT if any user start the URI with /ARCHIACjkaejksfsdjkhdfsj , this request will be send to server .

 

Same is TRUE with /archiacportalsdfjkbasdjkfbsd .

 

If there any way to discard the junk characters with HTTP 404 error when someone start the URI with above STRINGS ???

 

 

  

  • /ARCHIACjkaejksfsdjkhdfsj matches your first starts_with condition. Can you give a couple more examples of good matches versus bad matches? I'm not sure I have a clear enough picture of what is "good" to provide you a proper solution. On top of that, a few comments:

     

    • I'm not sure how anything gets through to the server with your HTTP::host. If you string tolower that, it'll never match xyz.APAC.com. I'm guessing that's just a sanitization error for adding to DC?
    • You don't need a string tolower on the HTTP::host. That is case insensitive by RFC.
    • You almost certainly do not want matches_regex there. Recommendation would be to use if, elseif, else strategy here, so by virtue of not matching your first two cases, the else will handle your 404 for everything else.

     

    • Hi Jason Rahm ,

       

      I have re-written my irule using some variable for flexible matching :

       

      Here is irule that i am using :

       

      when HTTP_REQUEST {

      set host [string tolower [HTTP::host]]

      set uri [HTTP::uri]

      if {$host equals "xyz.apac.com."} {

      set context [getfield $uri "/" 2]

       

      if {($context ne "archiacserver") and ($context ne "archiacportal") and ($context ne "archiac")} {

      HTTP::respond 404 content {Page Not Found Page Not Found}

      } elseif { ($uri starts_with "/archiacserver")} {

      HTTP::uri [string map {"/archiacserver" "/archiac"} [HTTP::uri]

      HTTP::redirect "https://$host[HTTP::uri]"

      pool PL_BNE_ENT_6443

      return

      } elseif {$uri starts_with "/archiac"} {

      pool PL_BNE_ENT_6443

      }elseif {$uri starts_with "/archiacportal"} {

      pool PL_BNE_ENT_archiacportal_443

      return

      }

      }

      }

       

       

      SO below are GOOD matching :

       

      www.xyz.apac.com/archiacserver

      www.xyz.apac.com/archiacserver/

      www.xyz.apac.com/archiacserver/abcde/efgh

      www.xyz.apac.com/archiacportal

       

       

      BAD MATCH

       

      www.xyz.apac.com/dhghasgharchiacserver

      www.xyz.apac.com/ARCHIACSERVER

      www.xyz.apac.com/archiacserveradjefjaehfje

      www.xyz.apac.com/archiacserver)*)*)*)*)*)

      www.xyz.apac.com/archiacPORTAL

      www.xyz.apac.com/ARCCHIACPORTALjdfbjdsfjasd

       

      etc etc

       

      SO my code work fine with testing and loading the APP through LB and also now looks like error handling works fine . . But i am seeing some issues with session kick out .

       

      For example if i try to load www.xyz.apac.com/archiacserver/admin/login , this works fine .Page load up with username and password and work perfectly .

       

      But if i hover to some tab after logged in and click , the session times out and ask for a re-login .

       

      we are not doing any Load balancing , simply sending the traffic to pool and my pool is configured with ACTIVE/STANDBY nodes using priority group .< 1 with one node being on 10 and other on 5 .

       

      So no cookie persistence needed .

       

      ANy suggestions ?? something wrong with my irule ?

       

      No session kick out when i hit the node directly .

       

      Thanks

      • JRahm's avatar
        JRahm
        Icon for Admin rankAdmin

        If you are trying to match the path and NOT the query parameters, you'd be better off using HTTP::path, which only includes path information for that instead of HTTP::uri, which includes both path and query parameters.

         

        For your badmatch, are you saying those are still matching, or that they are no longer matching?

         

        finally, are you seeing any tcl errors in the logs when the sessions are being "kicked out"?

         

        FYI, I'm going to be out on PTO for the next few days

  • Hi Jason ,

     

    Thanks for writing me back .

     

    The bad matches are no longer matching .This is the irule I am using as POC :

     

    when HTTP_REQUEST {

    set host [string tolower [HTTP::host]]

    set uri [HTTP::uri]

    if {$host equals "xyz.apac.com."} {

    set context [getfield $uri "/" 2]

     

    if {($context ne "archiacserver") and ($context ne "archiacportal") and ($context ne "archiac")} {

    HTTP::respond 404 content {Page Not Found Page Not Found}

    } elseif { ($uri starts_with "/archiacserver")} {

    HTTP::uri [string map {"/archiacserver" "/archiac"} [HTTP::uri]

    pool PL_BNE_ENT_6443

    return

    } elseif {$uri starts_with "/archiac"} {

    pool PL_BNE_ENT_6443

    }elseif {$uri starts_with "/archiacportal"} {

    pool PL_BNE_ENT_archiacportal_443

    return

    }

    }

    }

     

     

     

    Regarding the error , I found I need to set x-forwarded for host with the HTTP profile and also at the server end they need to set a web context URL for re-write .

     

    The issue is now fixed . Thanks !