class SetHeaderHandler(RequestHandler):
def get(self):
- # tests the validity of web.RequestHandler._INVALID_HEADER_CHAR_RE
- # should match the invalid characters from
- # https://www.rfc-editor.org/rfc/rfc9110#name-field-values
+ # tests the validity of web.RequestHandler._VALID_HEADER_CHARS
illegal_chars = [chr(o) for o in range(0, 0x20)]
illegal_chars.append(chr(0x7f))
illegal_chars.remove('\t')
except ValueError as e:
if "Unsafe header value" not in str(e):
raise
+
+ # an empty header value is valid as well
+ self.set_header("X-Foo", "")
+
self.finish(b"ok")
if name in self._headers:
del self._headers[name]
- _INVALID_HEADER_CHAR_RE = re.compile(r"[\x00-\x08\x0a-\x1f\x7f]")
+ # https://www.rfc-editor.org/rfc/rfc9110#name-field-values
+ _VALID_HEADER_CHARS = re.compile(r"[\x09\x20-\x7e\x80-\xff]*")
def _convert_header_value(self, value: _HeaderTypes) -> str:
# Convert the input value to a str. This type check is a bit
raise TypeError("Unsupported header value %r" % value)
# If \n is allowed into the header, it is possible to inject
# additional headers or split the request.
- if RequestHandler._INVALID_HEADER_CHAR_RE.search(retval):
+ if RequestHandler._VALID_HEADER_CHARS.fullmatch(retval) is None:
raise ValueError("Unsafe header value %r", retval)
return retval