]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
httputil: Add types for elements of HTTPHeaders
authorBen Darnell <ben@bendarnell.com>
Fri, 7 Jun 2024 18:42:28 +0000 (14:42 -0400)
committerBen Darnell <ben@bendarnell.com>
Fri, 7 Jun 2024 18:53:09 +0000 (14:53 -0400)
Revealed an issue in websocket.py in which bytes were used when it
should have been str. This avoided being a bug because something
down the line was converting it to str but it was still a logical
type error.

The change to httputil.py was taken from #3329 (thanks mslynch).

Closes #3329
Fixes #3328

tornado/httputil.py
tornado/web.py
tornado/websocket.py

index 9ce992d82b3ea9a2239a99ab4c4c8edc2b001ac1..81550353303cc17d56d0116df107db539028d6cd 100644 (file)
@@ -62,6 +62,12 @@ if typing.TYPE_CHECKING:
     from asyncio import Future  # noqa: F401
     import unittest  # noqa: F401
 
+    # This can be done unconditionally in the base class of HTTPHeaders
+    # after we drop support for Python 3.8.
+    StrMutableMapping = collections.abc.MutableMapping[str, str]
+else:
+    StrMutableMapping = collections.abc.MutableMapping
+
 # To be used with str.strip() and related methods.
 HTTP_WHITESPACE = " \t"
 
@@ -76,7 +82,7 @@ def _normalize_header(name: str) -> str:
     return "-".join([w.capitalize() for w in name.split("-")])
 
 
-class HTTPHeaders(collections.abc.MutableMapping):
+class HTTPHeaders(StrMutableMapping):
     """A dictionary that maintains ``Http-Header-Case`` for all keys.
 
     Supports multiple values per key via a pair of new methods,
index 039396470f8c701a8284a24612b18793b2b5840f..21d0cad68978dbeb9028a4d612a4fd68598b4d73 100644 (file)
@@ -1596,14 +1596,14 @@ class RequestHandler(object):
         # information please see
         # http://www.djangoproject.com/weblog/2011/feb/08/security/
         # http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails
-        token = (
+        input_token = (
             self.get_argument("_xsrf", None)
             or self.request.headers.get("X-Xsrftoken")
             or self.request.headers.get("X-Csrftoken")
         )
-        if not token:
+        if not input_token:
             raise HTTPError(403, "'_xsrf' argument missing from POST")
-        _, token, _ = self._decode_xsrf_token(token)
+        _, token, _ = self._decode_xsrf_token(input_token)
         _, expected_token, _ = self._get_raw_xsrf_token()
         if not token:
             raise HTTPError(403, "'_xsrf' argument has invalid format")
index 8f0e0aefe89c7699450014e6d68490a0b05defc4..0127303076ace775960f2a2d775a870eda3c2a99 100644 (file)
@@ -1380,7 +1380,7 @@ class WebSocketClientConnection(simple_httpclient._HTTPConnection):
             {
                 "Upgrade": "websocket",
                 "Connection": "Upgrade",
-                "Sec-WebSocket-Key": self.key,
+                "Sec-WebSocket-Key": to_unicode(self.key),
                 "Sec-WebSocket-Version": "13",
             }
         )