Issue #1096 new

keepalive semantics must correspond to _reported_ server HTTP protocol.

Anonymous created an issue

When the cherrypy server in 1.1 mode responds to a 1.0 request, it reports back that it is speaking 1.1. For a reverse proxy, such as Fiddler http://www.fiddler2.com/fiddler2/version.asp this means that it must also use the keep-alive semantics of 1.1.

The particular defect manifests itself thus: A client makes a 1.0 request to the server through the fiddler proxy. The proxy responds with 1.1 but no "Connection: close" header. The proxy sees this and keeps the connection open downstream to the client.

Note that the proxy never sees the EOF sent by the server since it is reading a 1.1 response and stops reading once the header and content_length data have arrived.

The fix is simple: lines 852 in wsgiserver/init.py change to: {{{

!python

if self.response_protocol == 'HTTP/1.1':

        # CCP change: Stick with the _reported_ protocol.  A proxy will see
        # only the response and assume that the server follows those
        # keep-alive semantics.
        if self.server.protocol == 'HTTP/1.1':
            # The server writes 1.1 in the response. Stick with
            # the protocol.
            if self.close_connection:
                self.outheaders.append(("Connection", "close"))
        else:
            # response is HTTP/1.0

}}}

Reported by kristjan@ccpgames.com

Comments (1)

  1. Robert Brewer

    The version number reported in the first line of an HTTP message is not the version of the message; instead, it is the version of HTTP for which the sender is at least conditionally compliant. Therefore, a CherryPy server will always report itself as 1.1 even if the client reports itself as 1.0 (unless you explicitly downgrade the CherryPy server via server.protocol).

    The `response_protocol` starts at 1.0 and is only upgraded to 1.1 if both the server is 1.1 and the client reports itself as 1.1. This is why the code you references emits Keep-Alive if "Server and/or client are HTTP/1.0" (see the comments). Therefore, if the client reports itself as 1.0 and the server replies with no "Connection: close" header (and I assume no "Keep-Alive" header) then it will close the connection. If the proxy passed the message through with the HTTP/1.0 version declaration, then it is responsible to recognize that no header means "close the connection". If it rewrote the message and reported ''itself'' as 1.1, then either it is seeing a "Connection: close" header and mishandling it, or the resource is being streamed to the client by the server. If this problem persists, it would help to do a tcpdump of the entire conversation, including both the client-to-proxy traffic and the proxy-to-server traffic to isolate the fault.

  2. Log in to comment