209
209
return code, data
211
# The parent class use 0 to minimize the requests, but since we can't
212
# exploit the results as soon as they are received (pycurl limitation) we'd
213
# better issue more requests and provide a more responsive UI do the cost
214
# of more latency costs.
215
# If you modify this, think about modifying the comment in http/__init__.py
217
_get_max_size = 4 * 1024 * 1024
211
219
def _get_ranged(self, relpath, offsets, tail_amount):
212
220
"""Make a request for just part of the file."""
213
221
curl = self._get_curl()
224
232
code = curl.getinfo(pycurl.HTTP_CODE)
225
# mutter('header:\n%r', header.getvalue())
226
headers = _extract_headers(header.getvalue(), abspath)
227
# handle_response will raise NoSuchFile, etc based on the response code
228
return code, response.handle_response(abspath, code, headers, data)
234
if code == 404: # not found
235
raise errors.NoSuchFile(abspath)
236
elif code in (400, 416):
237
# We don't know which, but one of the ranges we specified was
239
raise errors.InvalidHttpRange(abspath, range_header,
240
'Server return code %d'
241
% curl.getinfo(pycurl.HTTP_CODE))
242
msg = self._parse_headers(header)
243
return code, response.handle_response(abspath, code, msg, data)
245
def _parse_headers(self, status_and_headers):
246
"""Transform the headers provided by curl into an HTTPMessage"""
247
status_and_headers.seek(0)
249
status_and_headers.readline()
250
msg = httplib.HTTPMessage(status_and_headers)
230
253
def _post(self, body_bytes):
231
254
fake_file = StringIO(body_bytes)
242
265
self._curl_perform(curl, header, ['Expect: '])
244
267
code = curl.getinfo(pycurl.HTTP_CODE)
245
headers = _extract_headers(header.getvalue(), abspath)
246
return code, response.handle_response(abspath, code, headers, data)
268
msg = self._parse_headers(header)
269
return code, response.handle_response(abspath, code, msg, data)
248
271
def _raise_curl_http_error(self, curl, info=None):
249
272
code = curl.getinfo(pycurl.HTTP_CODE)
297
320
raise errors.ConnectionError(
298
321
'curl connection error (%s)\non %s' % (e[1], url))
299
322
elif e[0] == CURLE_PARTIAL_FILE:
300
# Pycurl itself has detected a short read. We do
301
# not have all the information for the
302
# ShortReadvError, but that should be enough
323
# Pycurl itself has detected a short read. We do not have all
324
# the information for the ShortReadvError, but that should be
303
326
raise errors.ShortReadvError(url,
304
327
offset='unknown', length='unknown',
305
328
actual='unknown',
306
329
extra='Server aborted the request')
307
# jam 20060713 The code didn't use to re-raise the exception here,
308
# but that seemed bogus
310
331
code = curl.getinfo(pycurl.HTTP_CODE)
311
332
if code in (301, 302, 303, 307):
312
333
url = curl.getinfo(pycurl.EFFECTIVE_URL)
313
headers = _extract_headers(header.getvalue(), url)
314
redirected_to = headers['Location']
334
msg = self._parse_headers(header)
335
redirected_to = msg.getheader('location')
315
336
raise errors.RedirectRequested(url,
317
338
is_permanent=(code == 301),