From 1bbaac259086d69feda70b3822fd056f64bc15e5 Mon Sep 17 00:00:00 2001 From: Martin Richard Date: Fri, 2 Dec 2016 16:49:28 +0100 Subject: [PATCH 1/5] use raw_host in Host request header --- aiohttp/client_reqrep.py | 2 +- tests/test_client_request.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index c1901b1f29d..bce128bf259 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -165,7 +165,7 @@ def update_auto_headers(self, skip_auto_headers): # add host if hdrs.HOST not in used_headers: - netloc = self.url.host + netloc = self.url.raw_host if not self.url.is_default_port(): netloc += ':' + str(self.url.port) self.headers[hdrs.HOST] = netloc diff --git a/tests/test_client_request.py b/tests/test_client_request.py index 659502249a5..d0572501282 100644 --- a/tests/test_client_request.py +++ b/tests/test_client_request.py @@ -143,6 +143,16 @@ def test_host_header_host_with_nondefault_port(make_request): assert req.headers['HOST'] == 'python.org:99' +def test_host_header_host_idna_encode(make_request): + req = make_request('get', 'http://xn--9caa.com') + assert req.headers['HOST'] == 'xn--9caa.com' + + +def test_host_header_host_unicode(make_request): + req = make_request('get', 'http://éé.com') + assert req.headers['HOST'] == 'xn--9caa.com' + + def test_host_header_explicit_host(make_request): req = make_request('get', 'http://python.org/', headers={'host': 'example.com'}) From 2cce77addc872603cd8ed58aa820c51a857d6b3e Mon Sep 17 00:00:00 2001 From: Martin Richard Date: Fri, 2 Dec 2016 17:21:41 +0100 Subject: [PATCH 2/5] Use raw_host in CONNECT request --- aiohttp/client_reqrep.py | 2 +- tests/test_proxy.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index bce128bf259..27bcf8f2c44 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -437,7 +437,7 @@ def send(self, writer, reader): # - not CONNECT proxy must send absolute form URI # - most common is origin form URI if self.method == hdrs.METH_CONNECT: - path = '{}:{}'.format(self.url.host, self.url.port) + path = '{}:{}'.format(self.url.raw_host, self.url.port) elif self.proxy and not self.ssl: path = str(self.url) else: diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 5d13125328b..164a14caa80 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -62,6 +62,21 @@ def test_proxy_auth(self): "proxy_auth must be None or BasicAuth() tuple", ) + @mock.patch('aiohttp.Request') + def test_connect_request_with_unicode_host(self, Request_mock): + loop = mock.Mock() + request = ClientRequest("CONNECT", URL("http://éé.com/"), + loop=loop) + + request.response_class = mock.Mock() + request.write_bytes = mock.Mock() + request.write_bytes.return_value = asyncio.Future(loop=loop) + request.write_bytes.return_value.set_result(None) + request.send(mock.Mock(), mock.Mock()) + + Request_mock.assert_called_with(mock.ANY, mock.ANY, "xn--9caa.com:80", + mock.ANY) + def test_proxy_connection_error(self): connector = aiohttp.TCPConnector(loop=self.loop) connector._resolve_host = make_mocked_coro( From d15df773813c9fa70601c4efda1d9d607e2f1d0b Mon Sep 17 00:00:00 2001 From: Martin Richard Date: Fri, 2 Dec 2016 17:46:21 +0100 Subject: [PATCH 3/5] Use raw_host in CookieJar --- aiohttp/cookiejar.py | 4 ++-- tests/test_cookiejar.py | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py index c3c7b9164a4..b9dd25936e9 100644 --- a/aiohttp/cookiejar.py +++ b/aiohttp/cookiejar.py @@ -91,7 +91,7 @@ def _expire_cookie(self, when, domain, name): def update_cookies(self, cookies, response_url=URL()): """Update cookies.""" - hostname = response_url.host + hostname = response_url.raw_host if not self._unsafe and is_ip_address(hostname): # Don't accept cookies from IPs @@ -168,7 +168,7 @@ def filter_cookies(self, request_url=URL()): """Returns this jar's cookies filtered by their attributes.""" self._do_expiration() filtered = SimpleCookie() - hostname = request_url.host or "" + hostname = request_url.raw_host or "" is_not_secure = request_url.scheme not in ("https", "wss") for cookie in self: diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py index 54290f419f9..8c0f6dc9456 100644 --- a/tests/test_cookiejar.py +++ b/tests/test_cookiejar.py @@ -162,6 +162,32 @@ def test_save_load(loop, cookies_to_send, cookies_to_receive): assert jar_test == cookies_to_receive +def test_update_cookie_with_unicode_domain(loop): + cookies = ( + "idna-domain-first=first; Domain=xn--9caa.com; Path=/;", + "idna-domain-second=second; Domain=xn--9caa.com; Path=/;", + ) + + jar = CookieJar(loop=loop) + jar.update_cookies(SimpleCookie(cookies[0]), URL("http://éé.com/")) + jar.update_cookies(SimpleCookie(cookies[1]), URL("http://xn--9caa.com/")) + + jar_test = SimpleCookie() + for cookie in jar: + jar_test[cookie.key] = cookie + + assert jar_test == SimpleCookie(" ".join(cookies)) + + +def test_filter_cookie_with_unicode_domain(loop): + jar = CookieJar(loop=loop) + jar.update_cookies(SimpleCookie( + "idna-domain-first=first; Domain=xn--9caa.com; Path=/; " + )) + assert len(jar.filter_cookies(URL("http://éé.com"))) == 1 + assert len(jar.filter_cookies(URL("http://xn--9caa.com"))) == 1 + + def test_ctor_ith_default_loop(loop): asyncio.set_event_loop(loop) jar = CookieJar() From 970a2f2723754cf7b26e110fade38368a1a1b884 Mon Sep 17 00:00:00 2001 From: Martin Richard Date: Fri, 2 Dec 2016 17:58:54 +0100 Subject: [PATCH 4/5] update CHANGES fo #1444 --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 77a2b158d96..292ca801c3a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -32,7 +32,7 @@ CHANGES - Fix bugs with client proxy target path and proxy host with port #1413 -- +- Fix bugs related to the use of unicode hostnames #1444 - From c3d64df02154558e3feec760350a1622a7089562 Mon Sep 17 00:00:00 2001 From: Martin Richard Date: Sat, 3 Dec 2016 11:24:49 +0100 Subject: [PATCH 5/5] add unicode to spelling_wordlist.txt --- docs/spelling_wordlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 2fcc04f160f..f0eb75833ca 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -203,6 +203,7 @@ tp tuples UI un +unicode unittest Unittest unix