From: Ben Darnell Date: Sun, 15 May 2011 23:59:43 +0000 (-0700) Subject: Fix cookie handling after python3 encoding changes. Add tests. X-Git-Tag: v2.0.0~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bd2a0ffdbeb76c03023c271bdfb721aaa43d834;p=thirdparty%2Ftornado.git Fix cookie handling after python3 encoding changes. Add tests. --- diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index 123d82ee0..0d9171caa 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -51,6 +51,34 @@ class SecureCookieTest(LogTrapTestCase): # it gets rejected assert handler.get_secure_cookie('foo') is None +class CookieTest(AsyncHTTPTestCase, LogTrapTestCase): + def get_app(self): + class SetCookieHandler(RequestHandler): + def get(self): + # Try setting cookies with different argument types + # to ensure that everything gets encoded correctly + self.set_cookie("str", "asdf") + self.set_cookie("unicode", u"qwer") + self.set_cookie("bytes", b("zxcv")) + + class GetCookieHandler(RequestHandler): + def get(self): + self.write(self.get_cookie("foo")) + + return Application([ + ("/set", SetCookieHandler), + ("/get", GetCookieHandler)]) + + def test_set_cookie(self): + response = self.fetch("/set") + self.assertEqual(response.headers.get_list("Set-Cookie"), + ["str=asdf; Path=/", + "unicode=qwer; Path=/", + "bytes=zxcv; Path=/"]) + + def test_get_cookie(self): + response = self.fetch("/get", headers={"Cookie": "foo=bar"}) + self.assertEqual(response.body, b("bar")) class AuthRedirectRequestHandler(RequestHandler): def initialize(self, login_url): diff --git a/tornado/web.py b/tornado/web.py index 61a674dcf..6d168897f 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -265,7 +265,8 @@ class RequestHandler(object): self._cookies = Cookie.BaseCookie() if "Cookie" in self.request.headers: try: - self._cookies.load(self.request.headers["Cookie"]) + self._cookies.load( + escape.native_str(self.request.headers["Cookie"])) except: self.clear_all_cookies() return self._cookies @@ -285,8 +286,9 @@ class RequestHandler(object): See http://docs.python.org/library/cookie.html#morsel-objects for available attributes. """ - name = utf8(name) - value = utf8(value) + # The cookie library only accepts type str, in both python 2 and 3 + name = escape.native_str(name) + value = escape.native_str(value) if re.search(r"[\x00-\x20]", name + value): # Don't let us accidentally inject bad stuff raise ValueError("Invalid cookie %r: %r" % (name, value)) @@ -888,7 +890,7 @@ class RequestHandler(object): lines.extend([(utf8(n) + b(": ") + utf8(v)) for n, v in self._headers.iteritems()]) for cookie_dict in getattr(self, "_new_cookies", []): for cookie in cookie_dict.values(): - lines.append(b("Set-Cookie: ") + cookie.OutputString(None)) + lines.append(utf8("Set-Cookie: " + cookie.OutputString(None))) return b("\r\n").join(lines) + b("\r\n\r\n") def _log(self):