28
from bzrlib import errors
29
from bzrlib import errors, ui
29
30
from bzrlib.trace import mutter
30
31
from bzrlib.transport import (
33
from bzrlib.smart import medium, protocol
34
from bzrlib.ui import ui_factory
34
from bzrlib.smart import medium
37
37
# TODO: This is not used anymore by HttpTransport_urllib
61
61
if password is not None:
62
62
password = urllib.unquote(password)
64
password = ui_factory.get_password(
64
password = ui.ui_factory.get_password(
65
65
prompt='HTTP %(user)s@%(host)s password',
66
66
user=username, host=host)
67
67
password_manager.add_password(None, host, username, password)
254
def _retry_get(self, relpath, ranges, exc_info):
255
"""A GET request have failed, let's retry with a simpler request."""
258
# The server does not gives us enough data or
259
# bogus-looking result, let's try again with
260
# a simpler request if possible.
261
if self._range_hint == 'multi':
262
self._range_hint = 'single'
263
mutter('Retry %s with single range request' % relpath)
265
elif self._range_hint == 'single':
266
self._range_hint = None
267
mutter('Retry %s without ranges' % relpath)
270
# Note that since the offsets and the ranges may not
271
# be in the same order, we don't try to calculate a
272
# restricted single range encompassing unprocessed
274
code, f = self._get(relpath, ranges)
275
return try_again, code, f
277
# We tried all the tricks, but nothing worked. We
278
# re-raise original exception; the 'mutter' calls
279
# above will indicate that further tries were
281
raise exc_info[0], exc_info[1], exc_info[2]
254
283
def readv(self, relpath, offsets):
255
284
"""Get parts of the file at the given relative path.
260
289
ranges = self.offsets_to_ranges(offsets)
261
290
mutter('http readv of %s collapsed %s offsets => %s',
262
291
relpath, len(offsets), ranges)
263
code, f = self._get(relpath, ranges)
297
code, f = self._get(relpath, ranges)
298
except (errors.InvalidRange, errors.ShortReadvError), e:
299
try_again, code, f = self._retry_get(relpath, ranges,
264
302
for start, size in offsets:
272
310
if len(data) != size:
273
311
raise errors.ShortReadvError(relpath, start, size,
274
312
actual=len(data))
275
except (errors.InvalidRange, errors.ShortReadvError):
276
# The server does not gives us enough data or
277
# bogus-looking result, let's try again with
278
# a simpler request if possible.
279
if self._range_hint == 'multi':
280
self._range_hint = 'single'
281
mutter('Retry %s with single range request' % relpath)
283
elif self._range_hint == 'single':
284
self._range_hint = None
285
mutter('Retry %s without ranges' % relpath)
288
# Note that since the offsets and the
289
# ranges may not be in the same order we
290
# dont't try to calculate a restricted
291
# single range encompassing unprocessed
292
# offsets. Note that we replace 'f' here
293
# and that it may need cleaning one day
294
# before being thrown that way.
295
code, f = self._get(relpath, ranges)
297
# We tried all the tricks, nothing worked
313
except (errors.InvalidRange, errors.ShortReadvError), e:
314
# Note that we replace 'f' here and that it
315
# may need cleaning one day before being
317
try_again, code, f = self._retry_get(relpath, ranges,
319
# After one or more tries, we get the data.
300
320
yield start, data