Skip to content

Commit

Permalink
Merge pull request #1445 from Martiusweb/client_idna
Browse files Browse the repository at this point in the history
Fix support of IDNA in Client
  • Loading branch information
asvetlov authored Dec 3, 2016
2 parents 718313b + c3d64df commit 912d871
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

-

Expand Down
4 changes: 2 additions & 2 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ tp
tuples
UI
un
unicode
unittest
Unittest
unix
Expand Down
10 changes: 10 additions & 0 deletions tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'})
Expand Down
26 changes: 26 additions & 0 deletions tests/test_cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
15 changes: 15 additions & 0 deletions tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 912d871

Please sign in to comment.