Forum Discussion

Ben_Wilson_2412's avatar
Jul 11, 2013

Changing HTTP Reponse status code

Hi,

 

I've been asked to change the reponse HTTP Status code for custom 404 pages to "404" instead of 200.

 

It looks like this is possible by checking if the request is for /404.jsp, capturing the payload with HTTP::Payload and the using HTTP::Response to generate a new response with the captured payload.

 

 

Is there an easier way?

 

I'm concerned about capturing all the payload response on the F5. There could be thousands of 404 and I'm afraid of running the device out of memeory. Is that a valid concern?

 

 

Thanks!

 

Ben

 

8 Replies

  • Can you clarify? Usually a 404 is generated by the server in response to a request for something that doesn't exist. The user wouldn't ask for a "404.jsp" page. That's just what the server would send if it couldn't honor the actual request. And which payload to you have to capture (request or response)?
  • can we just check HTTP::status in response and send out 200?

    e.g.

    [root@ve10:Active] config  b virtual bar list
    virtual bar {
       snat automap
       pool foo
       destination 172.28.19.252:80
       ip protocol 6
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve10:Active] config  b pool foo list
    pool foo {
       members 200.200.200.101:80 {}
    }
    [root@ve10:Active] config  b rule myrule list
    rule myrule {
       when HTTP_RESPONSE {
      if { [HTTP::status] == 404 } {
        HTTP::respond 200
      }
    }
    }
    
     test
    
    [root@ve10:Active] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.18.204.228(49530) <-> 172.28.19.252(80)
    1373588986.4110 (0.0048)  C>S
    ---------------------------------------------------------------
    GET /not_real_uri HTTP/1.1
    Host: 172.28.19.252
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.10(49530) <-> 200.200.200.101(80)
    1373588986.4121 (0.0010)  C>S
    ---------------------------------------------------------------
    GET /not_real_uri HTTP/1.1
    Host: 172.28.19.252
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    
    ---------------------------------------------------------------
    
    1373588986.4132 (0.0010)  S>C
    ---------------------------------------------------------------
    HTTP/1.1 404 Not Found
    Date: Fri, 12 Jul 2013 00:40:19 GMT
    Server: Apache/2.2.3 (CentOS)
    Content-Length: 288
    Connection: close
    Content-Type: text/html; charset=iso-8859-1
    
    ...snipped...
    ---------------------------------------------------------------
    
    1373588986.4133 (0.0022)  S>C
    ---------------------------------------------------------------
    HTTP/1.0 200 OK
    Server: BigIP
    Connection: close
    Content-Length: 0
    
    ---------------------------------------------------------------
    
  • Sure, right now what's in place is:

     

     

    when HTTP_RESPONSE {

     

    if { [HTTP::status] == "404" or [HTTP::status] == "501" }{

     

    HTTP::redirect "/error/404.jsp"

     

    }

     

    }

     

     

    So what's happening is the 404 response is getting intercepted and replaced with a 302 with the error page URL.

     

    Since the error page exists, when the 302 is followed, you'll get a 200 from that request.

     

     

    From the client's perspective, they asked for a resource that didn't exist, received a redirect and then a valid response. The valid response is an error page which is obvious to a user, but to an automated system, it appears as though the request was valid.

     

     

    Does that make more sense?

     

     

    Thanks,

     

    Ben

     

  • when HTTP_RESPONSE {

     

    if { [HTTP::status] == "404" or [HTTP::status] == "501" }{

     

    HTTP::redirect "/error/404.jsp"

     

    }

     

    }so, does this work?

     

     

    by the way, have you ever tried HTTP::retry instead of HTTP::redirect? so, client does not need to send another request (i.e. /error/404.jsp).

     

     

    HTTP::retry

     

    https://devcentral.f5.com/wiki/irules.http__retry.ashx
  • Posted By nitass on 07/11/2013 11:02 PM

     

    when HTTP_RESPONSE {

     

    if { [HTTP::status] == "404" or [HTTP::status] == "501" }{

     

    HTTP::redirect "/error/404.jsp"

     

    }

     

    } so, does this work?

     

     

    by the way, have you ever tried HTTP::retry instead of HTTP::redirect? so, client does not need to send another request (i.e. /error/404.jsp).

     

     

    HTTP::retry

     

    https://devcentral.f5.com/wiki/irules.http__retry.ashx

     

    It works in that the client is sent a 302 to the error page.

     

    The condition I'm looking to modify is the subsequent request the client will make for the /error/404.jsp page.

     

    We want the HTTP Status for this request to be 404.

     

     

    Thanks!

     

  • We want the HTTP Status for this request to be 404.is it something like this?

     

     

    Need to change the HTTP Status code. (spark's reply)

     

    https://devcentral.f5.com/community/group/aft/2161382/asg/50

     

     

    e.g.

     

    [root@ve10:Active] config  b virtual bar list
    virtual bar {
       snat automap
       pool foo
       destination 172.28.19.252:80
       ip protocol 6
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve10:Active] config  b pool foo list
    pool foo {
       members 200.200.200.101:80 {}
    }
    [root@ve10:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
      set is_404 0
      if { [HTTP::uri] eq "/error/404.jsp" } {
        set is_404 1
      }
    }
    when SERVER_CONNECTED {
      TCP::collect 12
    }
    when SERVER_DATA {
      if { $is_404 } {
        set payload [TCP::payload 12]
        regsub 200 $payload 404 payload
        TCP::payload replace 0 12 $payload
      }
      TCP::release
      TCP::collect 12
    }
    }
    
    [root@ve10:Active] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.20.17(38929) <-> 172.28.19.252(80)
    1373613950.6180 (0.0018)  C>S
    ---------------------------------------------------------------
    GET /error/404.jsp HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.19.252
    Accept: */*
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.10(38929) <-> 200.200.200.101(80)
    1373613950.6191 (0.0010)  C>S
    ---------------------------------------------------------------
    GET /error/404.jsp HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.19.252
    Accept: */*
    
    ---------------------------------------------------------------
    
    1373613950.6211 (0.0020)  S>C
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Fri, 12 Jul 2013 07:36:23 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Fri, 12 Jul 2013 07:35:31 GMT
    ETag: "4185d1-1d-8e2db6c0"
    Accept-Ranges: bytes
    Content-Length: 29
    Connection: close
    Content-Type: text/plain; charset=UTF-8
    
    this is /error/404.jsp file.
    ---------------------------------------------------------------
    
    1373613950.6212 (0.0031)  S>C
    ---------------------------------------------------------------
    HTTP/1.1 404 OK
    Date: Fri, 12 Jul 2013 07:36:23 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Fri, 12 Jul 2013 07:35:31 GMT
    ETag: "4185d1-1d-8e2db6c0"
    Accept-Ranges: bytes
    Content-Length: 29
    Connection: close
    Content-Type: text/plain; charset=UTF-8
    
    this is /error/404.jsp file.
    ---------------------------------------------------------------
    
  • I believe you should also be able to use strictly HTTP events:

    
    when HTTP_REQUEST {
    if { [HTTP::uri] equals "/error/test.jsp" } {
    set is404 1
    }
    }
    when HTTP_RESPONSE {
    if { [info exists is404] } {
    HTTP::collect [HTTP::header Content-Length]
    }
    }
    when HTTP_RESPONSE_DATA {
    HTTP::respond 404 content [HTTP::payload]
    }