220
220
re.IGNORECASE | re.MULTILINE)
223
def _is_multipart(content_type):
224
return content_type.startswith('multipart/byteranges;')
223
227
def handle_response(url, code, headers, response):
224
228
"""Interpret the code & headers and return a HTTP response.
235
239
ranges indicated by the headers.
237
241
content_type = headers['Content-Type']
238
mutter('handling response code %s ctype %s', response.code,
242
mutter('handling response code %s ctype %s', code, content_type)
241
if response.code == 206 and _is_multipart(content_type):
244
if code == 206 and _is_multipart(content_type):
242
245
# Full fledged multipart response
243
246
return HttpMultipartRangeResponse(url, content_type, response)
244
elif response.code == 206:
245
248
# A response to a range request, but not multipart
246
content_range = response.headers['Content-Range']
249
content_range = headers['Content-Range']
247
250
return HttpRangeResponse(url, content_range, response)
248
elif response.code == 200:
249
252
# A regular non-range response, unfortunately the result from
250
253
# urllib doesn't support seek, so we wrap it in a StringIO
251
return StringIO(response.read())
252
elif response.code == 404:
254
tell = getattr(response, 'tell', None)
256
return StringIO(response.read())
253
259
raise NoSuchFile(url)
255
raise BzrError("HTTP couldn't handle code %s", response.code)
261
raise BzrError("HTTP couldn't handle code %s", code)