83
86
return pycurl.__dict__.get(symbol, default)
88
# Yes, weird but returned on weird http error (invalid status line)
89
CURLE_FTP_WEIRD_SERVER_REPLY = _get_pycurl_errcode(
90
'E_FTP_WEIRD_SERVER_REPLY', 8)
85
91
CURLE_COULDNT_CONNECT = _get_pycurl_errcode('E_COULDNT_CONNECT', 7)
86
92
CURLE_COULDNT_RESOLVE_HOST = _get_pycurl_errcode('E_COULDNT_RESOLVE_HOST', 6)
87
93
CURLE_COULDNT_RESOLVE_PROXY = _get_pycurl_errcode('E_COULDNT_RESOLVE_PROXY', 5)
290
298
return code, response.handle_response(abspath, code, msg, data)
293
def _raise_curl_http_error(self, curl, info=None):
301
def _raise_curl_http_error(self, curl, info=None, body=None):
302
"""Common curl->bzrlib error translation.
304
Some methods may choose to override this for particular cases.
306
The URL and code are automatically included as appropriate.
308
:param info: Extra information to include in the message.
310
:param body: File-like object from which the body of the page can be
294
313
code = curl.getinfo(pycurl.HTTP_CODE)
295
314
url = curl.getinfo(pycurl.EFFECTIVE_URL)
296
# Some error codes can be handled the same way for all
316
response_body = body.read()
317
plaintext_body = unhtml_roughly(response_body)
299
322
raise errors.TransportError(
300
323
'Server refuses to fulfill the request (403 Forbidden)'
324
' for %s: %s' % (url, plaintext_body))
306
329
msg = ': ' + info
307
330
raise errors.InvalidHttpResponse(
308
url, 'Unable to handle http code %d%s' % (code,msg))
331
url, 'Unable to handle http code %d%s: %s'
332
% (code, msg, plaintext_body))
310
334
def _debug_cb(self, kind, text):
311
if kind in (pycurl.INFOTYPE_HEADER_IN, pycurl.INFOTYPE_DATA_IN,
312
pycurl.INFOTYPE_SSL_DATA_IN):
335
if kind in (pycurl.INFOTYPE_HEADER_IN, pycurl.INFOTYPE_DATA_IN):
313
336
self._report_activity(len(text), 'read')
314
337
if (kind == pycurl.INFOTYPE_HEADER_IN
315
338
and 'http' in debug.debug_flags):
316
mutter('< %s' % text)
317
elif kind in (pycurl.INFOTYPE_HEADER_OUT, pycurl.INFOTYPE_DATA_OUT,
318
pycurl.INFOTYPE_SSL_DATA_OUT):
339
trace.mutter('< %s' % (text.rstrip(),))
340
elif kind in (pycurl.INFOTYPE_HEADER_OUT, pycurl.INFOTYPE_DATA_OUT):
319
341
self._report_activity(len(text), 'write')
320
342
if (kind == pycurl.INFOTYPE_HEADER_OUT
321
343
and 'http' in debug.debug_flags):
322
mutter('> %s' % text)
345
for line in text.rstrip().splitlines():
346
# People are often told to paste -Dhttp output to help
347
# debug. Don't compromise credentials.
349
header, details = line.split(':', 1)
352
if header in ('Authorization', 'Proxy-Authorization'):
353
line = '%s: <masked>' % (header,)
355
trace.mutter('> ' + '\n> '.join(lines))
323
356
elif kind == pycurl.INFOTYPE_TEXT and 'http' in debug.debug_flags:
324
mutter('* %s' % text)
357
trace.mutter('* %s' % text.rstrip())
358
elif (kind in (pycurl.INFOTYPE_TEXT, pycurl.INFOTYPE_SSL_DATA_IN,
359
pycurl.INFOTYPE_SSL_DATA_OUT)
360
and 'http' in debug.debug_flags):
361
trace.mutter('* %s' % text)
326
363
def _set_curl_options(self, curl):
327
364
"""Set options for all requests"""
359
396
except pycurl.error, e:
360
397
url = curl.getinfo(pycurl.EFFECTIVE_URL)
361
mutter('got pycurl error: %s, %s, %s, url: %s ',
398
trace.mutter('got pycurl error: %s, %s, %s, url: %s ',
363
400
if e[0] in (CURLE_COULDNT_RESOLVE_HOST,
364
401
CURLE_COULDNT_RESOLVE_PROXY,
365
402
CURLE_COULDNT_CONNECT,
403
CURLE_FTP_WEIRD_SERVER_REPLY,
366
404
CURLE_GOT_NOTHING,
367
405
CURLE_SSL_CACERT,
368
406
CURLE_SSL_CACERT_BADFILE,