Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR #10014/50d23aee backport][3.11] Improve performance of serializing headers #10016

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/10014.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved performance of serializing HTTP headers -- by :user:`bdraco`.
28 changes: 14 additions & 14 deletions aiohttp/_http_writer.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -100,30 +100,24 @@ cdef inline int _write_str(Writer* writer, str s):
# --------------- _serialize_headers ----------------------

cdef str to_str(object s):
typ = type(s)
if typ is str:
if type(s) is str:
return <str>s
elif typ is _istr:
elif type(s) is _istr:
return PyObject_Str(s)
elif not isinstance(s, str):
raise TypeError("Cannot serialize non-str key {!r}".format(s))
else:
return str(s)


cdef void _safe_header(str string) except *:
if "\r" in string or "\n" in string:
raise ValueError(
"Newline or carriage return character detected in HTTP status message or "
"header. This is a potential security issue."
)


def _serialize_headers(str status_line, headers):
cdef Writer writer
cdef object key
cdef object val
cdef bytes ret
cdef str key_str
cdef str val_str

_init_writer(&writer)

Expand All @@ -136,16 +130,22 @@ def _serialize_headers(str status_line, headers):
raise

for key, val in headers.items():
_safe_header(to_str(key))
_safe_header(to_str(val))
key_str = to_str(key)
val_str = to_str(val)

if "\r" in key_str or "\n" in key_str or "\r" in val_str or "\n" in val_str:
raise ValueError(
"Newline or carriage return character detected in HTTP status message or "
"header. This is a potential security issue."
)

if _write_str(&writer, to_str(key)) < 0:
if _write_str(&writer, key_str) < 0:
raise
if _write_byte(&writer, b':') < 0:
raise
if _write_byte(&writer, b' ') < 0:
raise
if _write_str(&writer, to_str(val)) < 0:
if _write_str(&writer, val_str) < 0:
raise
if _write_byte(&writer, b'\r') < 0:
raise
Expand Down
Loading