From c216c4869921cb9ade491704f945d6f1401ccbcc Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Wed, 12 Nov 2014 23:33:50 +1000 Subject: Close #19494: add urrlib.request.HTTPBasicPriorAuthHandler This auth handler adds the Authorization header to the first HTTP request rather than waiting for a HTTP 401 Unauthorized response from the server as the default HTTPBasicAuthHandler does. This allows working with websites like https://api.github.com which do not follow the strict interpretation of RFC, but more the dicta in the end of section 2 of RFC 2617: > A client MAY preemptively send the corresponding Authorization > header with requests for resources in that space without receipt > of another challenge from the server. Similarly, when a client > sends a request to a proxy, it may reuse a userid and password in > the Proxy-Authorization header field without receiving another > challenge from the proxy server. See section 4 for security > considerations associated with Basic authentication. Patch by Matej Cepl. --- Lib/urllib/request.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'Lib/urllib/request.py') diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index e0c8116373..36ae1ef461 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -916,6 +916,21 @@ class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): return response +class HTTPBasicPriorAuthHandler(HTTPBasicAuthHandler): + handler_order = 400 + + def http_request(self, req): + if not req.has_header('Authorization'): + user, passwd = self.passwd.find_user_password(None, req.host) + credentials = '{0}:{1}'.format(user, passwd).encode() + auth_str = base64.standard_b64encode(credentials).decode() + req.add_unredirected_header('Authorization', + 'Basic {}'.format(auth_str.strip())) + return req + + https_request = http_request + + # Return n random bytes. _randombytes = os.urandom -- cgit v1.2.1