Forum Discussion

LyonsG_85618's avatar
LyonsG_85618
Icon for Cirrostratus rankCirrostratus
Jan 13, 2015

Rewrite HTTP response when error code received

Hi

I need to capture 500 errors and when I receive them return a preformated error page. This page will sit on a different domain (where the digital publishing team can update it quickly) and therefore I need to rewrite HOST/URI and send to different pool.

So far I have the following:

    when HTTP_RESPONSE {
        switch -glob [HTTP::status] {
    "500" {
            HTTP::header replace Host "new.domain.com"
            HTTP::uri "/error"
            pool /TEST/POOL_FOR_NEW_DOMAIN
    }

Unfortunately you cannot use HTTP::uri in an HTTP_RESPONSE.

I do not want to do a 302 redirect as that would mean client would see the new domain.

Is there a simple way round this?

I know we can host page on BIG-IP (ifiles) but as mentioned - publishing team want access to the page to change wording quickly.

Thanks in advance for your help.

9 Replies

  • Since you can't access HTTP::uri in the response, you'll need to set a variable in HTTP_REQUEST so you can access it.

     

    If you look at the HTTP::retry command (see the last example on that page), you may be able to retry the request and change the request so you can get a different response from another server. (You may have to add some logic in your HTTP_REQUEST event to handle whatever host/location you use in the updated request).

     

    If you ever wanted to just return a custom payload from within your iRule, you could use something like this codeshare entry to get you started.

     

    Hope this helps

     

  • Thanks Michael

     

    I do not want to attempt to get response from another server. I just want to redirect/rewrite to the error page.

     

    I dont think HTTP:retry will help with this.

     

    The payload probably wont work either as i am not 'collecting' any data.

     

  • You originally mentioned you don't want to use a 302 redirect for the client, but want to get the error page from somewhere your publishing team can update quickly, right? In that case, if they need a page to update on a server, the HTTP::retry would allow you to basically do a redirect that the user never sees because it's all contained in the F5.

    Otherwise if you just have custom content to return to the user, I think you can use the

    HTTP::respond 200 content ""
    method within HTTP_RESPONSE to send back some custom html.

  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    Here's another approach that doesn't require HTTP::uri. The rule may or may not work as-is since I pulled out environment-specific stuff and inserted your new pool and host. However, it should still provide a template.

     

    when HTTP_RESPONSE {
    
        if { [HTTP::status] equals 403 || [HTTP::status] equals 404 } {
    
             Retrieve the not-found page if the HTTP status is 403, 404
             Note: Retrieving the page is a valid request, which means that the server will respond with a 200 OK.
                   This necessitates that we collect the payload so we can later construct a custom response with
                   the proper HTTP response code (404) but with the payload (HTML) from this request.
    
            if { ![info exists retry] } {
    
                set retry 1
    
                HTTP::header replace Host "new.domain.com"
                pool /TEST/POOL_FOR_NEW_DOMAIN
                HTTP::retry "GET /error/not-found/ HTTP/1.1\r\nHost:$requested_host\r\n\r\n"
    
            }
    
        }
    
        if { [info exists is404] } {
    
            if { [HTTP::status] equals 200 } {
    
                 store the payload of the not-found page if the HTTP status is 200
                 (this means that the error page was found on the file system)
    
                HTTP::collect [HTTP::header Content-Length]
    
            } else {
    
                 No error page was found in the folder. Construct a generic error page
                 and send it to the client.
    
                log local0.debug "is404 true, but there's no error page on the file system. ([HTTP::status])"
    
                HTTP::respond 404 content {
    
                    
                        
                            
                        
                    
    
                }
    
            }
    
        }
    
    }
    
    when HTTP_RESPONSE_DATA {
    
         Construct the response with the payload of the not-found page that we collected earlier and
         with the HTTP Response Code "404".
    
        HTTP::respond 404 content [HTTP::payload] "Content-Type" "text/html"
    
    }
  • Thnaks for all the help. I have taken a rather simplistic view on this and just done a simple HTTP::respond

     HTTP::respond 302 noserver Location "https://existing.domain.com/federror"
    

    Then in the top part of the iRule i have added:

    } elseif {($requestedURI starts_with "/error") or ($requestedURI starts_with "/content")} {
          pool /PARTITION/POOL_HOSTING_ERROR_PAGE
    

    And this is working.

    Thanks

    • Arie's avatar
      Arie
      Icon for Altostratus rankAltostratus
      While that technically may work, it could result in problems with SEO (Search Engine Optimization).
    • LyonsG_85618's avatar
      LyonsG_85618
      Icon for Cirrostratus rankCirrostratus
      Arie - I shoudl have made it clear - the domain will remain the same - its just the request for content that will go to the pool of content servers. So i believe SEO will remain unaltered.