92
92
CURLE_COULDNT_RESOLVE_PROXY = _get_pycurl_errcode('E_COULDNT_RESOLVE_PROXY', 5)
93
93
CURLE_GOT_NOTHING = _get_pycurl_errcode('E_GOT_NOTHING', 52)
94
94
CURLE_PARTIAL_FILE = _get_pycurl_errcode('E_PARTIAL_FILE', 18)
95
CURLE_SEND_ERROR = _get_pycurl_errcode('E_SEND_ERROR', 55)
97
98
class PyCurlTransport(HttpTransportBase):
256
257
def _post(self, body_bytes):
258
curl = self._get_curl()
259
abspath, data, header = self._setup_request(curl, '.bzr/smart')
260
curl.setopt(pycurl.POST, 1)
257
261
fake_file = StringIO(body_bytes)
258
curl = self._get_curl()
259
# Other places that use the Curl object (returned by _get_curl)
260
# for GET requests explicitly set HTTPGET, so it should be safe to
261
# re-use the same object for both GETs and POSTs.
262
curl.setopt(pycurl.POST, 1)
263
262
curl.setopt(pycurl.POSTFIELDSIZE, len(body_bytes))
264
263
curl.setopt(pycurl.READFUNCTION, fake_file.read)
265
abspath, data, header = self._setup_request(curl, '.bzr/smart')
266
264
# We override the Expect: header so that pycurl will send the POST
267
265
# body immediately.
268
self._curl_perform(curl, header, ['Expect: '])
267
self._curl_perform(curl, header, ['Expect: '])
268
except pycurl.error, e:
269
if e[0] == CURLE_SEND_ERROR:
270
# When talking to an HTTP/1.0 server, getting a 400+ error code
271
# triggers a bug in some combinations of curl/kernel in rare
272
# occurrences. Basically, the server closes the connection
273
# after sending the error but the client (having received and
274
# parsed the response) still try to send the request body (see
275
# bug #225020 and its upstream associated bug). Since the
276
# error code and the headers are known to be available, we just
277
# swallow the exception, leaving the upper levels handle the
279
mutter('got pycurl error in POST: %s, %s, %s, url: %s ',
280
e[0], e[1], e, abspath)
270
285
code = curl.getinfo(pycurl.HTTP_CODE)
271
286
msg = self._parse_headers(header)