1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-13 09:16:14 +01:00

Backport a fix from Python 2.7 upstream for urllib2.

This change makes basic authentication fail after first unsuccessful
attempt (instead of automatically retrying) and thus prevents unnecessary
failed login attempts.

This change also allows printing the contents of an HTTP 401 message to
the user.
This commit is contained in:
Hemmo Nieminen 2016-06-15 03:14:41 -07:00
parent 05ad9efae3
commit 326abe0c8b

View File

@ -42,6 +42,7 @@ import os
import re import re
import sys import sys
import ssl import ssl
import warnings
try: try:
from http.cookiejar import LWPCookieJar, CookieJar from http.cookiejar import LWPCookieJar, CookieJar
@ -57,7 +58,7 @@ except ImportError:
from httplib import HTTPConnection, HTTPResponse from httplib import HTTPConnection, HTTPResponse
from StringIO import StringIO from StringIO import StringIO
from urlparse import urlsplit from urlparse import urlsplit
from urllib2 import URLError, HTTPBasicAuthHandler, HTTPCookieProcessor, HTTPPasswordMgrWithDefaultRealm, ProxyHandler from urllib2 import URLError, HTTPBasicAuthHandler, HTTPCookieProcessor, HTTPPasswordMgrWithDefaultRealm, ProxyHandler, AbstractBasicAuthHandler
from urllib2 import AbstractHTTPHandler, build_opener, proxy_bypass, HTTPSHandler from urllib2 import AbstractHTTPHandler, build_opener, proxy_bypass, HTTPSHandler
from . import OscConfigParser from . import OscConfigParser
@ -479,38 +480,33 @@ def _build_opener(apiurl):
# workaround for http://bugs.python.org/issue9639 # workaround for http://bugs.python.org/issue9639
authhandler_class = HTTPBasicAuthHandler authhandler_class = HTTPBasicAuthHandler
if sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 1) \ if sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 9):
and not 'reset_retry_count' in dir(HTTPBasicAuthHandler):
print('warning: your urllib2 version seems to be broken. ' \
'Using a workaround for http://bugs.python.org/issue9639', file=sys.stderr)
class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler): class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
def http_error_401(self, *args): # The following two functions were backported from upstream 2.7.
response = HTTPBasicAuthHandler.http_error_401(self, *args) def http_error_auth_reqed(self, authreq, host, req, headers):
self.retried = 0 authreq = headers.get(authreq, None)
return response
def http_error_404(self, *args): if authreq:
self.retried = 0 mo = AbstractBasicAuthHandler.rx.search(authreq)
return None if mo:
scheme, quote, realm = mo.groups()
if quote not in ['"', "'"]:
warnings.warn("Basic Auth Realm was unquoted",
UserWarning, 2)
if scheme.lower() == 'basic':
return self.retry_http_basic_auth(host, req, realm)
authhandler_class = OscHTTPBasicAuthHandler
elif sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 1):
class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
def http_error_404(self, *args):
self.reset_retry_count()
return None
authhandler_class = OscHTTPBasicAuthHandler
elif sys.version_info >= (2, 6, 5) and sys.version_info < (2, 6, 6):
# workaround for broken urllib2 in python 2.6.5: wrong credentials
# lead to an infinite recursion
class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
def retry_http_basic_auth(self, host, req, realm): def retry_http_basic_auth(self, host, req, realm):
# don't retry if auth failed user, pw = self.passwd.find_user_password(realm, host)
if req.get_header(self.auth_header, None) is not None: if pw is not None:
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
if req.get_header(self.auth_header, None) == auth:
return None
req.add_unredirected_header(self.auth_header, auth)
return self.parent.open(req, timeout=req.timeout)
else:
return None return None
return HTTPBasicAuthHandler.retry_http_basic_auth(self, host, req, realm)
authhandler_class = OscHTTPBasicAuthHandler authhandler_class = OscHTTPBasicAuthHandler