Commit 44795773 authored by Senthil Kumaran's avatar Senthil Kumaran

merge from 3.2 - Fix Issue #13642: Unquote before b64encoding user:password...

merge from 3.2 - Fix Issue #13642: Unquote before b64encoding user:password during Basic Authentication.
parents 6c3dd7ea c5c5a145
...@@ -12,6 +12,8 @@ import os ...@@ -12,6 +12,8 @@ import os
import sys import sys
import tempfile import tempfile
from base64 import b64encode
def hexescape(char): def hexescape(char):
"""Escape char as RFC 2396 specifies""" """Escape char as RFC 2396 specifies"""
hex_repr = hex(ord(char))[2:].upper() hex_repr = hex(ord(char))[2:].upper()
...@@ -42,8 +44,8 @@ class FakeHTTPMixin(object): ...@@ -42,8 +44,8 @@ class FakeHTTPMixin(object):
class FakeSocket(io.BytesIO): class FakeSocket(io.BytesIO):
io_refs = 1 io_refs = 1
def sendall(self, str): def sendall(self, data):
pass FakeHTTPConnection.buf = data
def makefile(self, *args, **kwds): def makefile(self, *args, **kwds):
self.io_refs += 1 self.io_refs += 1
...@@ -65,8 +67,13 @@ class FakeHTTPMixin(object): ...@@ -65,8 +67,13 @@ class FakeHTTPMixin(object):
io.BytesIO.close(self) io.BytesIO.close(self)
class FakeHTTPConnection(http.client.HTTPConnection): class FakeHTTPConnection(http.client.HTTPConnection):
# buffer to store data for verification in urlopen tests.
buf = None
def connect(self): def connect(self):
self.sock = FakeSocket(fakedata) self.sock = FakeSocket(fakedata)
self._connection_class = http.client.HTTPConnection self._connection_class = http.client.HTTPConnection
http.client.HTTPConnection = FakeHTTPConnection http.client.HTTPConnection = FakeHTTPConnection
...@@ -268,6 +275,25 @@ Content-Type: text/html; charset=iso-8859-1 ...@@ -268,6 +275,25 @@ Content-Type: text/html; charset=iso-8859-1
finally: finally:
self.unfakehttp() self.unfakehttp()
def test_userpass_inurl_w_spaces(self):
self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
try:
userpass = "a b:c d"
url = "http://{}@python.org/".format(userpass)
fakehttp_wrapper = http.client.HTTPConnection
authorization = ("Authorization: Basic %s\r\n" %
b64encode(userpass.encode("ASCII")).decode("ASCII"))
fp = urlopen(url)
# The authorization header must be in place
self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
self.assertEqual(fp.readline(), b"Hello!")
self.assertEqual(fp.readline(), b"")
# the spaces are quoted in URL so no match
self.assertNotEqual(fp.geturl(), url)
self.assertEqual(fp.getcode(), 200)
finally:
self.unfakehttp()
class urlretrieve_FileTests(unittest.TestCase): class urlretrieve_FileTests(unittest.TestCase):
"""Test urllib.urlretrieve() on local files""" """Test urllib.urlretrieve() on local files"""
...@@ -1111,6 +1137,9 @@ class Utility_Tests(unittest.TestCase): ...@@ -1111,6 +1137,9 @@ class Utility_Tests(unittest.TestCase):
self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb')) self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb')) self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b')) self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
def test_thishost(self): def test_thishost(self):
"""Test the urllib.request.thishost utility function returns a tuple""" """Test the urllib.request.thishost utility function returns a tuple"""
......
...@@ -1693,11 +1693,13 @@ class URLopener: ...@@ -1693,11 +1693,13 @@ class URLopener:
if not host: raise IOError('http error', 'no host given') if not host: raise IOError('http error', 'no host given')
if proxy_passwd: if proxy_passwd:
proxy_passwd = unquote(proxy_passwd)
proxy_auth = base64.b64encode(proxy_passwd.encode()).decode('ascii') proxy_auth = base64.b64encode(proxy_passwd.encode()).decode('ascii')
else: else:
proxy_auth = None proxy_auth = None
if user_passwd: if user_passwd:
user_passwd = unquote(user_passwd)
auth = base64.b64encode(user_passwd.encode()).decode('ascii') auth = base64.b64encode(user_passwd.encode()).decode('ascii')
else: else:
auth = None auth = None
......
...@@ -442,6 +442,9 @@ Core and Builtins ...@@ -442,6 +442,9 @@ Core and Builtins
Library Library
------- -------
- Issue #13642: Unquote before b64encoding user:password during Basic
Authentication. Patch contributed by Joonas Kuorilehto.
- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow - Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow
tests. tests.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment