19
19
from bzrlib.transport import Transport, register_transport
20
20
from bzrlib.errors import (TransportNotPossible, NoSuchFile,
21
TransportError, ConnectionError)
21
NonRelativePath, TransportError)
23
23
from cStringIO import StringIO
24
import urllib, urllib2
27
27
from bzrlib.errors import BzrError, BzrCheckError
29
29
from bzrlib.trace import mutter
32
def extract_auth(url, password_manager):
34
Extract auth parameters from am HTTP/HTTPS url and add them to the given
35
password manager. Return the url, minus those auth parameters (which
38
assert url.startswith('http://') or url.startswith('https://')
39
scheme, host = url.split('//', 1)
41
host, path = host.split('/', 1)
47
auth, host = host.split('@', 1)
49
username, password = auth.split(':', 1)
51
username, password = auth, None
53
host, port = host.split(':', 1)
55
# FIXME: if password isn't given, should we ask for it?
56
if password is not None:
57
username = urllib.unquote(username)
58
password = urllib.unquote(password)
59
password_manager.add_password(None, host, username, password)
60
url = scheme + '//' + host + port + path
65
34
mutter("get_url %s" % url)
66
manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
67
url = extract_auth(url, manager)
68
auth_handler = urllib2.HTTPBasicAuthHandler(manager)
69
opener = urllib2.build_opener(auth_handler)
70
url_f = opener.open(url)
35
url_f = urllib2.urlopen(url)
38
class HttpTransportError(TransportError):
73
41
class HttpTransport(Transport):
74
42
"""This is the transport agent for http:// access.
151
119
cleaner if we just do an http HEAD request, and parse
156
path = self.abspath(relpath)
123
f = get_url(self.abspath(relpath))
158
124
# Without the read and then close()
159
125
# we tend to have busy sockets.
163
129
except urllib2.URLError, e:
164
mutter('url error code: %s for has url: %r', e.code, path)
165
130
if e.code == 404:
168
133
except IOError, e:
169
mutter('io error: %s %s for has url: %r',
170
e.errno, errno.errorcode.get(e.errno), path)
171
134
if e.errno == errno.ENOENT:
173
raise TransportError(orig_error=e)
136
raise HttpTransportError(orig_error=e)
175
138
def get(self, relpath, decode=False):
176
139
"""Get the file at the given relative path.
178
141
:param relpath: The relative path to the file
182
path = self.abspath(relpath)
184
except urllib2.HTTPError, e:
185
mutter('url error code: %s for has url: %r', e.code, path)
187
raise NoSuchFile(path, extra=e)
144
return get_url(self.abspath(relpath))
145
except urllib2.URLError, e:
146
if getattr(e, 'code', None) == 404:
147
raise NoSuchFile(msg = "Error retrieving %s: %s"
148
% (self.abspath(relpath), str(e)),
189
151
except (BzrError, IOError), e:
190
if hasattr(e, 'errno'):
191
mutter('io error: %s %s for has url: %r',
192
e.errno, errno.errorcode.get(e.errno), path)
193
if e.errno == errno.ENOENT:
194
raise NoSuchFile(path, extra=e)
195
raise ConnectionError(msg = "Error retrieving %s: %s"
152
raise NoSuchFile(msg = "Error retrieving %s: %s"
196
153
% (self.abspath(relpath), str(e)),