Rev 3655: (vila) Fix bug #225020 by catching CURLE_SEND_ERROR in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Aug 28 10:22:22 BST 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3655
revision-id: pqm at pqm.ubuntu.com-20080828092217-98wmtek2p8cie8sc
parent: pqm at pqm.ubuntu.com-20080828063210-o4du3ibqwr46bd1f
parent: v.ladeuil+lp at free.fr-20080828083226-bwo4amdhmp4caw0t
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2008-08-28 10:22:17 +0100
message:
  (vila) Fix bug #225020 by catching CURLE_SEND_ERROR
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
    ------------------------------------------------------------
    revno: 3654.1.1
    revision-id: v.ladeuil+lp at free.fr-20080828083226-bwo4amdhmp4caw0t
    parent: pqm at pqm.ubuntu.com-20080828063210-o4du3ibqwr46bd1f
    parent: v.ladeuil+lp at free.fr-20080827202611-8l16umo6ylc4rbnw
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: trunk
    timestamp: Thu 2008-08-28 10:32:26 +0200
    message:
      Fix bug #225020 by catching CURLE_SEND_ERROR
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
    ------------------------------------------------------------
    revno: 3651.1.1
    revision-id: v.ladeuil+lp at free.fr-20080827202611-8l16umo6ylc4rbnw
    parent: pqm at pqm.ubuntu.com-20080827044137-4ox67ehr4bxtj7b0
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: 225020-select-poll
    timestamp: Wed 2008-08-27 22:26:11 +0200
    message:
      Fix bug #225020 by catching CURLE_SEND_ERROR error.
      
      * bzrlib/transport/http/_pycurl.py:
      (PyCurlTransport._post): There is a race condition between
      HTTP/1.0 servers refusing a POST request and the curl library
      trying to send the body request anyway. In rare occurrences, the
      connection is already closed.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
=== modified file 'NEWS'
--- a/NEWS	2008-08-28 01:55:04 +0000
+++ b/NEWS	2008-08-28 08:32:26 +0000
@@ -32,6 +32,10 @@
     * ``bzr rm`` is now aliased to ``bzr del`` for the convenience of svn
       users. (Robert Collins, #205416)
 
+    * Catch the infamous "select/poll returned error" which occurs when
+      pycurl try to send a body request to an HTTP/1.0 server which has
+      already refused to handle the request. (Vincent Ladeuil, #225020)
+
     * ``FTPTransport.stat()`` would return ``0000`` as the permission bits
       for the containing ``.bzr/`` directory (it does not implement
       permissions). This would cause us to set all subdirectories to

=== modified file 'bzrlib/transport/http/_pycurl.py'
--- a/bzrlib/transport/http/_pycurl.py	2008-05-18 13:59:54 +0000
+++ b/bzrlib/transport/http/_pycurl.py	2008-08-27 20:26:11 +0000
@@ -92,6 +92,7 @@
 CURLE_COULDNT_RESOLVE_PROXY = _get_pycurl_errcode('E_COULDNT_RESOLVE_PROXY', 5)
 CURLE_GOT_NOTHING = _get_pycurl_errcode('E_GOT_NOTHING', 52)
 CURLE_PARTIAL_FILE = _get_pycurl_errcode('E_PARTIAL_FILE', 18)
+CURLE_SEND_ERROR = _get_pycurl_errcode('E_SEND_ERROR', 55)
 
 
 class PyCurlTransport(HttpTransportBase):
@@ -254,18 +255,29 @@
         return msg
 
     def _post(self, body_bytes):
+        curl = self._get_curl()
+        abspath, data, header = self._setup_request(curl, '.bzr/smart')
+        curl.setopt(pycurl.POST, 1)
         fake_file = StringIO(body_bytes)
-        curl = self._get_curl()
-        # Other places that use the Curl object (returned by _get_curl)
-        # for GET requests explicitly set HTTPGET, so it should be safe to
-        # re-use the same object for both GETs and POSTs.
-        curl.setopt(pycurl.POST, 1)
         curl.setopt(pycurl.POSTFIELDSIZE, len(body_bytes))
         curl.setopt(pycurl.READFUNCTION, fake_file.read)
-        abspath, data, header = self._setup_request(curl, '.bzr/smart')
         # We override the Expect: header so that pycurl will send the POST
         # body immediately.
-        self._curl_perform(curl, header, ['Expect: '])
+        try:
+            self._curl_perform(curl, header, ['Expect: '])
+        except pycurl.error, e:
+            if e[0] == CURLE_SEND_ERROR:
+                # This has been observed when curl assumes a closed connection
+                # when talking to HTTP/1.0 servers, getting a 403, but trying
+                # to send the request body anyway. (see bug #225020)
+                code = curl.getinfo(pycurl.HTTP_CODE)
+                if code == 403:
+                    raise errors.InvalidHttpResponse(
+                        abspath,
+                        'Unexpected send error,'
+                        ' the server probably closed the connection')
+            # Re-raise otherwise
+            raise
         data.seek(0)
         code = curl.getinfo(pycurl.HTTP_CODE)
         msg = self._parse_headers(header)




More information about the bazaar-commits mailing list