Forum Discussion

Jay_Guerette's avatar
Jay_Guerette
Icon for Nimbostratus rankNimbostratus
Aug 29, 2007

HTTP 100 causes this rule to hang the connection

Using BIG-IP 9.2.5 Build 5.1; I have a legacy HTTP application that will throw an error with an 'HTTP 200' result code. I want to intercept this error, and display a friendly error page. In order to do this, I need to inspect the outgoing content, and look for an HTML page that contains the phrase "Application Error" at the top of the page.

 

 

The code included below works as expected; but it causes a failure with a file upload POST to an ASP page on an IIS server. The server sends an 'HTTP 100' result code, and the connection just hangs and eventually times out.

 

 

Am I missing something in my code?

 

 


when HTTP_RESPONSE {
    set status [getfield [HTTP::status] " " 1]
    if { [HTTP::header "Content-Type"] contains "text/html" && $status == 200 } {
        HTTP::collect [HTTP::header Content-Length]
    }
}
when HTTP_RESPONSE_DATA {
    if { [HTTP::payload] contains "Application Error" } {
        HTTP::respond 302 Location "/error/"
    }
}

 

 

Some people working on similar issues have suggested disabling OneConnect; I've tried that.
  • It's hard to guess what's going wrong. If the server is sending a 100 response code, then the iRule should not pass the first if in the HTTP_RESPONSE event and ignore the rest. I'd try to throw in some logging and see what shows up on the /var/log/ltm log file.

     

     

    when HTTP_RESPONSE {
        set status [getfield [HTTP::status] " " 1]
        log local0. "HTTP Status: $status"
        if { [HTTP::header "Content-Type"] contains "text/html" && $status == 200 } {
            log local0. "Collecting [HTTP::header Content-Length]..."
            HTTP::collect [HTTP::header Content-Length]
        }
    }
    when HTTP_RESPONSE_DATA {
        if { [HTTP::payload] contains "Application Error" } {
            log local0. "HTTP::payload contains Application Error - sending 302 response"
            HTTP::respond 302 Location "/error/"
        }
    }

     

     

    I'm wondering why you are doing a getfield on the HTTP::status. Are you finding that it is containing more than just the numeric status code?

     

     

    -Joe
  • The splitting of HTTP::status is most likely a leftover edit from one of the many iterations I've gone through in trying to resolve this issue. I've corrected it in my code.

     

     

    I'll add logging, as suggested, and see if I can get more inisght into the flow and details of the process.
  • I finally got this set up in my lab, using the following code:

     

     

    
    when HTTP_RESPONSE {
       if { [HTTP::header "Content-Type"] contains "text/html" && [HTTP::status] == 200 } {
          log local0. "Status [HTTP::status] Collecting [HTTP::header Content-Length]..."
          HTTP::collect [HTTP::header Content-Length]
          }
    }

     

     

    The behavior is the same, the browser receives a "HTTP/1.1 100 Continue", and the connection hangs.

     

     

    Curiously, the log entry is:

     

     

    Sep 27 12:16:58 tmm tmm[812]: Rule redirect_error : Status 200 Collecting 766...

     

     

    The client sees a 100 status yet the rule sees a 200 status?

     

     

    Update:

     

     

    I added:

     

    
    when HTTP_RESPONSE_CONTINUE {
       log local0. "Status [HTTP::status] continue"
    }

     

     

     

    And the logs say:

     

     

    Sep 27 13:26:41 tmm tmm[812]: Rule redirect_error : Status 100 continue

     

    Sep 27 13:26:41 tmm tmm[812]: Rule redirect_error : Status 200 Collecting 766..

     

     

    Update:

     

     

    The IIS logs say:

     

    ...POST /upload.asp 200 736 63 HTTP/1.1...

     

     

    So for some reason the content-header is saying 766 bytes, but the actual content is 736 bytes? That must be why it's hanging, waiting for the last 30 bytes....