146
146
def __init__(self, method, url, data=None, headers={},
147
147
origin_req_host=None, unverifiable=False,
148
148
connection=None, parent=None,):
149
# urllib2.Request will be confused if we don't extract
150
# authentification info before building the request
151
url, self.user, self.password = self.extract_auth(url)
152
self.auth = None # Until the first 401
153
149
urllib2.Request.__init__(self, url, data, headers,
154
150
origin_req_host, unverifiable)
155
151
self.method = method
159
155
self.redirected_to = None
160
156
# Unless told otherwise, redirections are not followed
161
157
self.follow_redirections = False
163
def extract_auth(self, url):
164
"""Extracts authentification information from url.
166
Get user and password from url of the form: http://user:pass@host/path
168
scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
171
auth, netloc = netloc.split('@', 1)
173
user, password = auth.split(':', 1)
175
user, password = auth, None
176
user = urllib.unquote(user)
177
if password is not None:
178
password = urllib.unquote(password)
183
url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
185
return url, user, password
158
self.set_auth(None, None, None) # Until the first 401
160
def set_auth(self, auth_scheme, user, password=None):
161
self.auth = auth_scheme
163
self.password = password
187
165
def get_method(self):
188
166
return self.method
197
175
def __init__(self):
198
176
urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
200
def add_password(self, realm, uri, user, passwd):
201
# uri could be a single URI or a sequence
202
if isinstance(uri, basestring):
204
if not realm in self.passwd:
205
self.passwd[realm] = {}
206
for default_port in True, False:
208
[self.reduce_uri(u, default_port) for u in uri])
209
self.passwd[realm][reduced_uri] = (user, passwd)
211
def find_user_password(self, realm, authuri):
212
domains = self.passwd.get(realm, {})
213
for default_port in True, False:
214
reduced_authuri = self.reduce_uri(authuri, default_port)
215
for uris, authinfo in domains.iteritems():
217
if self.is_suburi(uri, reduced_authuri):
219
if realm is not None:
220
return self.find_user_password(None, authuri)
223
def reduce_uri(self, uri, default_port=True):
224
"""Accept authority or URI and extract only the authority and path."""
225
# note HTTP URLs do not have a userinfo component
226
parts = urlparse.urlsplit(uri)
231
path = parts[2] or '/'
237
host, port = urllib.splitport(authority)
238
if default_port and port is None and scheme is not None:
242
if dport is not None:
243
authority = "%s:%d" % (host, dport)
244
return authority, path
247
179
class ConnectionHandler(urllib2.BaseHandler):
248
180
"""Provides connection-sharing by pre-processing requests.
789
721
https_request = http_request # FIXME: Need test
723
def http_error_401(self, req, fp, code, msg, headers):
724
"""Trap the 401 to gather the auth type."""
725
response = urllib2.HTTPBasicAuthHandler.http_error_401(self, req, fp,
728
if response is not None:
792
734
class HTTPErrorProcessor(urllib2.HTTPErrorProcessor):
793
735
"""Process HTTP error responses.