Forum Discussion

TMcGov_92811's avatar
TMcGov_92811
Icon for Nimbostratus rankNimbostratus
Dec 04, 2009

iRule for LTM to send HTTP Error code

Hello, I have a simple iRule that directs HTTP requests to certain pools based on the URI. If there is a URI that is not specified in the iRule, I would like the LTM to respond with an HTTP Error code such as a 404 or 503 instead of sending them to a default pool.

 

How is this constructed ?

 

 

For instance:

 

 

when HTTP_REQUEST {

 

if { [HTTP::uri] contains "/offAssoc/" or [HTTP::uri] contains "/ops-context-root/" or [HTTP::uri] contains "/vsserv-context-root/" } {

 

pool pool-pool1

 

} elseif {

 

[HTTP::uri] contains "/AVAMService/"} {

 

pool pool-pool2

 

} elseif {

 

[HTTP::uri] contains "/adsvc/"} {

 

pool pool-pool3

 

} elseif {

 

[HTTP::uri] contains "/provision/provisioningservice" or [HTTP::uri] contains "/profile/profileservice" or [HTTP::uri] contains "/logon/logonservice" or [HTTP::uri] contains "/module/enrichmentservice" or [HTTP::uri] contains "/initialuser/createinitialuserservice" or [HTTP::uri] contains "/batchCustomer/BatchCustomerService"} {

 

pool pool-pool4

 

} else {

 

***** LTM RESPONDS WITH A 404 ERROR !!!!!! *******

 

}

 

}

9 Replies

  • Use the HTTP_RESPONSE event to capture the errors you care about - from the docs (http://devcentral.f5.com/wiki/default.aspx/iRules/HTTP_RESPONSE.html) they have an example and links to tons of others:

     

     
     when HTTP_RESPONSE { 
       if { [HTTP::status] contains "404"} { 
         HTTP::redirect "http://www.siterequest.com/" 
       } 
     } 
     

     

     

    You could easily capture that error code and HTTP::retry against it, redirect it, serve back your own page, etc. - the sky is the limit!

     

     

    -Matt
  • Thanks but I'm not sure this is what i"m looking for..I want the LTM to generate the HTTP error and send it back to the client if the URI does not match one specified in the iRule.
  • You can use HTTP::respond (Click here) to send an HTTP response from an iRule. You could also use a switch statement to check the URI:

     
      
     when HTTP_REQUEST { 
      
         Check the requested URI 
        switch -glob [HTTP::uri] { 
           "*/offAssoc/*" - 
           "*/ops-context-root/*" - 
           "*/vsserv-context-root/*" { 
              pool pool-pool1 
           } 
           "*/AVAMService/*" { 
              pool pool-pool2 
           } 
           "*/adsvc/*" { 
              pool pool-pool3 
           } 
           "*/provision/provisioningservice*" - 
           "*/profile/profileservice*" - 
           "*/logon/logonservice*" - 
           "*/module/enrichmentservice*"  
           "*/initialuser/createinitialuserservice*" - 
           "*/batchCustomer/BatchCustomerService*" { 
              pool pool-pool4 
           } 
           default { 
              HTTP::respond 404 content {Page Not FoundPage Not Found} 
           } 
        } 
     } 
     

    Aaron
  • The syntax seems correct, and all the valid URIs are send to the proper pools. But when I enter a URI not listed here, my client browser simply gets the generic HTTP 404 File not found error instead of my customized one. Any ideas ?

     

     

    when HTTP_REQUEST {

     

    Check the requested URI

     

    switch -glob [HTTP::uri] {

     

    "*/offAssoc/*" -

     

    "*/ops-context-root/*" -

     

    "*/vsserv-context-root/*" {

     

    pool pool1

     

    }

     

    "*/AVAMService/*" {

     

    pool pool2

     

    }

     

    "*/adsvc/*" {

     

    pool pool3

     

    }

     

    "*/provision/provisioningservice*" -

     

    "*/profile/profileservice*" -

     

    "*/logon/logonservice*" -

     

    "*/module/enrichmentservice*" -

     

    "*/initialuser/createinitialuserservice*" -

     

    "*/batchCustomer/BatchCustomerService*" {

     

    pool pool4

     

    }

     

    default {

     

    HTTP::respond 404 content "Unrecognized request to [HTTP::uri]" "Content-Type" "text/html"

     

    }

     

    }

     

    }
  • Can you add logging to each switch case to see which pool the request is going to? Or are they only getting to the default case?

     

     

    Aaron
  • The "valid" requests (ones with the specified URIs) are going to the correct pools. When I enter an invalid URI, I expect the LTM to return my customized 404 error page, but I only get the generic one.

     

     

    This piece of code seems to do the trick however. Its technically not a 404 error page, but I think it should do the trick - I will check with my middleware team. I would like to figure out how to customize a 404 error page though in case they actually need a 404 response.

     

     

    default {

     

    HTTP::respond 200 content {

     

     

     

    Application Services - Page Not Valid

     

     

     

    The page you have requested is not valid.

     

     

    Please check the URL and try again.

     

     

     

    }

     

  •  

    Keep in mind that ( from : http://en.wikipedia.org/wiki/HTTP_404 )

     

     

    Internet Explorer (before Internet Explorer 7), however, will not display custom pages unless they are larger than 512 bytes, opting to instead display a "friendly" error page.

     

     

     

    So probably the LTM 'is' returning your error page but your browser doesn't show it.

     

     

    [ string repeat " " 500 ] could come in handy to test.

     

     

     

     

  • The curly braces prevent variable / command interpretation. You could use subst (http://www.tcl.tk/man/tcl8.4/TclCmd/subst.htm) or escape any double quotes and not use braces to include a command in a value. I haven't tested this but something like it should work. Note that I've set the HTML in a variable once in RULE_INIT rather than generating the HTML on every request.

    
    when RULE_INIT {
        HTML content to send.
        Need to escape double quotes, literal square braces and other characters?
        Example includes an escaped line break to shorten the long line.
       set static::custom_html "My Title with escaped \"double quotes\"\
       \[escaped literal square braces\]
    500 spaces here: [string repeat 500 " "]}] 
    }
    when HTTP_REQUEST {
    
        Send the HTML
       HTTP::respond 200 content $static::custom_html
    }
    

    Aaron