C. Scott Ananian <[EMAIL PROTECTED]> added the comment:

FWIW, the following code works around the issue for me:

class HTTPConnection(httplib.HTTPConnection):
    def request(self, method, url, body=None, headers={}):
        # patch upstream to recv() after we send, so that a closed
        # connection is discovered here rather than later in
        # HTTPResponse._read_status()
        try:
            self._send_request(method, url, body, headers)
            b = self.sock.recv(1, socket.MSG_PEEK)
            if b == '':
                self.close()
                raise socket.error(32) # sender closed connection.
        except socket.error, v:
            # trap 'Broken pipe' if we're allowed to automatically reconnect
            if v[0] != 32 or not self.auto_open:
                raise
            # try one more time
            self._send_request(method, url, body, headers)

In general, attempting to read a byte of the response just to trigger
the broken pipe error is suboptimal; it doesn't accurately distinguish
the "closed before received request" case from the "closed just after
received request" case.  For idempotent methods like GET and HEAD, this
doesn't matter, but it does for POST, etc.

There ought to be a better way to force the underlying OS to give you
the current 'closed' status on a socket which doesn't require your
trying to send/receive bytes.  The fundamental issue here is that the
TCP spec, and Linux, allow the request send to succeed even if TCP FIN
has been received from the other side -- the receipt of FIN after the
response is received is always going to be a race to some degree.

All of which is why the HTTP pipelining specs encourage you *not* to use
pipelining for non-idempotent requests.  The above patch could be
tweaked to only perform the MSG_PEEK and retry if this is the second or
later pipelined request.  Then, following the HTTP recommendations and
always calling HttpConnection.close()/HttpConnection.connect() before
invoking "unsafe" requests like POST, would make the whole thing safe.

_______________________________________
Python tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue3566>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to