diff --git a/CHANGES.rst b/CHANGES.rst index 8f2d5415c95..fe701196317 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -34,6 +34,8 @@ CHANGES - Fix bugs related to the use of unicode hostnames #1444 +- Preserve cookie quoting/escaping #1453 + - FileSender will send gzipped response if gzip version available #1426 - diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5410e461dab..2e1a1159c58 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -10,6 +10,7 @@ Alexander Bayandin Alexander Karpinsky Alexander Koshevoy Alexander Malev +Alexander Mohr Alexander Shorin Alexander Travov Alexandru Mihai diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 27bcf8f2c44..3b5b6c0d5fb 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -185,7 +185,10 @@ def update_cookies(self, cookies): for name, value in cookies.items(): if isinstance(value, http.cookies.Morsel): - c[value.key] = value.value + # Preserve coded_value + mrsl_val = value.get(value.key, http.cookies.Morsel()) + mrsl_val.set(value.key, value.value, value.coded_value) + c[name] = mrsl_val else: c[name] = value diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py index b9dd25936e9..78b666f8dac 100644 --- a/aiohttp/cookiejar.py +++ b/aiohttp/cookiejar.py @@ -195,7 +195,11 @@ def filter_cookies(self, request_url=URL()): if is_not_secure and cookie["secure"]: continue - filtered[name] = cookie.value + # It's critical we use the Morsel so the coded_value + # (based on cookie version) is preserved + mrsl_val = cookie.get(cookie.key, Morsel()) + mrsl_val.set(cookie.key, cookie.value, cookie.coded_value) + filtered[name] = mrsl_val return filtered diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py index 8c0f6dc9456..9d487f8654a 100644 --- a/tests/test_cookiejar.py +++ b/tests/test_cookiejar.py @@ -244,6 +244,16 @@ def test_preserving_ip_domain_cookies(loop): 'Cookie: shared-cookie=first') +def test_preserving_quoted_cookies(loop): + jar = CookieJar(loop=loop, unsafe=True) + jar.update_cookies(SimpleCookie( + "ip-cookie=\"second\"; Domain=127.0.0.1;" + )) + cookies_sent = jar.filter_cookies(URL("http://127.0.0.1/")).output( + header='Cookie:') + assert cookies_sent == 'Cookie: ip-cookie=\"second\"' + + def test_ignore_domain_ending_with_dot(loop): jar = CookieJar(loop=loop, unsafe=True) jar.update_cookies(SimpleCookie("cookie=val; Domain=example.com.;"), @@ -260,7 +270,7 @@ def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(None) - # N.B. those need to be overriden in child test cases + # N.B. those need to be overridden in child test cases self.jar = CookieJar(loop=self.loop) def tearDown(self):