diff -r 6d278f426417 Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst Fri Jul 05 18:05:29 2013 -1000 +++ b/Doc/library/urllib.request.rst Sat Jul 06 11:58:29 2013 +0200 @@ -170,6 +170,11 @@ *url* should be a string containing a valid URL. + .. versionchanged:: 3.4.0 + If the *url* string contains any whitespace characters (spaces, tabs, + newlines or carriage-returns), they will be quoted using + :func:`urllib.parse.quote`. No other characters will be converted. + *data* must be a bytes object specifying additional data to send to the server, or ``None`` if no such data is needed. Currently HTTP requests are the only ones that use *data*; the HTTP request will be a POST instead of a diff -r 6d278f426417 Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py Fri Jul 05 18:05:29 2013 -1000 +++ b/Lib/test/test_urllib.py Sat Jul 06 11:58:29 2013 +0200 @@ -1391,6 +1391,12 @@ request.method = 'HEAD' self.assertEqual(request.get_method(), 'HEAD') + def test_url_path_space_encoding(self): + Request = urllib.request.Request + request = Request("http://www.python.org/a b\tc\nd\re") + self.assertEqual(request.selector, "/a%20b%09c%0Ad%0De") + request = Request("http://www.python.org/a%20b%09c%0Ad%0De") + self.assertEqual(request.selector, "/a%20b%09c%0Ad%0De") class URL2PathNameTests(unittest.TestCase): diff -r 6d278f426417 Lib/urllib/parse.py --- a/Lib/urllib/parse.py Fri Jul 05 18:05:29 2013 -1000 +++ b/Lib/urllib/parse.py Sat Jul 06 11:58:29 2013 +0200 @@ -859,7 +859,7 @@ """splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" global _hostprog if _hostprog is None: - _hostprog = re.compile('^//([^/?]*)(.*)$') + _hostprog = re.compile('^//([^/?]*)(.*)$', re.DOTALL) match = _hostprog.match(url) if match: diff -r 6d278f426417 Lib/urllib/request.py --- a/Lib/urllib/request.py Fri Jul 05 18:05:29 2013 -1000 +++ b/Lib/urllib/request.py Sat Jul 06 11:58:29 2013 +0200 @@ -317,6 +317,8 @@ self.host, self.selector = splithost(rest) if self.host: self.host = unquote(self.host) + self.selector = re.sub(r'\s', lambda m: quote(m.group()), + self.selector) def get_method(self): """Return a string indicating the HTTP request method."""