1
# Copyright (C) 2005, 2006 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
21
21
from bzrlib import (
25
from bzrlib.trace import mutter
26
from bzrlib.transport.http import HttpTransportBase
27
# TODO: handle_response should be integrated into the _urllib2_wrappers
26
from bzrlib.transport import http
27
# TODO: handle_response should be integrated into the http/__init__.py
28
28
from bzrlib.transport.http.response import handle_response
29
29
from bzrlib.transport.http._urllib2_wrappers import (
35
class HttpTransport_urllib(HttpTransportBase):
35
class HttpTransport_urllib(http.HttpTransportBase):
36
36
"""Python urllib transport for http and https."""
38
38
# In order to debug we have to issue our traces in sync with
70
70
# Give back shared info
71
71
request.connection = connection
72
72
(auth, proxy_auth) = self._get_credentials()
73
# Clean the httplib.HTTPConnection pipeline in case the previous
74
# request couldn't do it
75
connection.cleanup_pipe()
74
77
# First request, intialize credentials.
75
78
# scheme and realm will be set by the _urllib2_wrappers.AuthHandler
85
88
request.auth = auth
86
89
request.proxy_auth = proxy_auth
88
mutter('%s: [%s]' % (request.method, request.get_full_url()))
89
91
if self._debuglevel > 0:
90
92
print 'perform: %s base: %s, url: %s' % (request.method, self.base,
91
93
request.get_full_url())
124
126
if range_header is not None:
125
127
accepted_errors.append(206)
126
128
accepted_errors.append(400)
129
accepted_errors.append(416)
127
130
bytes = 'bytes=' + range_header
128
131
headers = {'Range': bytes}
134
137
code = response.code
135
138
if code == 404: # not found
136
self._get_connection().fake_close()
137
139
raise errors.NoSuchFile(abspath)
140
elif code in (400, 416):
141
# We don't know which, but one of the ranges we specified was
143
raise errors.InvalidHttpRange(abspath, range_header,
144
'Server return code %d' % code)
139
data = handle_response(abspath, code, response.headers, response)
140
# Close response to free the httplib.HTTPConnection pipeline
141
self._get_connection().fake_close()
146
data = handle_response(abspath, code, response.info(), response)
142
147
return code, data
144
149
def _post(self, body_bytes):
145
150
abspath = self._remote_path('.bzr/smart')
146
151
response = self._perform(Request('POST', abspath, body_bytes))
147
152
code = response.code
148
data = handle_response(abspath, code, response.headers, response)
149
# Close response to free the httplib.HTTPConnection pipeline
150
self._get_connection().fake_close()
153
data = handle_response(abspath, code, response.info(), response)
151
154
return code, data
153
156
def _head(self, relpath):