78 lines
2.6 KiB
Diff
78 lines
2.6 KiB
Diff
From f016f0680e4ace6742b03a70cb0382ce86abe371 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Svetlov <andrew.svetlov@gmail.com>
|
|
Date: Sun, 31 Oct 2021 19:03:06 +0200
|
|
Subject: [PATCH] Raise '400: Content-Length can't be present with
|
|
Transfer-Encoding' if both Content-Length and Transfer-Encoding are sent by
|
|
peer (#6182)
|
|
|
|
---
|
|
CHANGES/6182.bugfix | 1 +
|
|
aiohttp/http_parser.py | 12 ++++++++++--
|
|
tests/test_http_parser.py | 15 ++++++++++++++-
|
|
3 files changed, 25 insertions(+), 3 deletions(-)
|
|
create mode 100644 CHANGES/6182.bugfix
|
|
|
|
diff --git a/CHANGES/6182.bugfix b/CHANGES/6182.bugfix
|
|
new file mode 100644
|
|
index 0000000000..28daaa328a
|
|
--- /dev/null
|
|
+++ b/CHANGES/6182.bugfix
|
|
@@ -0,0 +1 @@
|
|
+Raise ``400: Content-Length can't be present with Transfer-Encoding`` if both ``Content-Length`` and ``Transfer-Encoding`` are sent by peer by both C and Python implementations
|
|
diff --git a/aiohttp/http_parser.py b/aiohttp/http_parser.py
|
|
index 4a4ae31ae6..e1b86e8e4f 100644
|
|
--- a/aiohttp/http_parser.py
|
|
+++ b/aiohttp/http_parser.py
|
|
@@ -28,6 +28,7 @@
|
|
from .base_protocol import BaseProtocol
|
|
from .helpers import NO_EXTENSIONS, BaseTimerContext
|
|
from .http_exceptions import (
|
|
+ BadHttpMessage,
|
|
BadStatusLine,
|
|
ContentEncodingError,
|
|
ContentLengthError,
|
|
@@ -489,8 +490,15 @@ def parse_headers(
|
|
|
|
# chunking
|
|
te = headers.get(hdrs.TRANSFER_ENCODING)
|
|
- if te and "chunked" in te.lower():
|
|
- chunked = True
|
|
+ if te is not None:
|
|
+ te_lower = te.lower()
|
|
+ if "chunked" in te_lower:
|
|
+ chunked = True
|
|
+
|
|
+ if hdrs.CONTENT_LENGTH in headers:
|
|
+ raise BadHttpMessage(
|
|
+ "Content-Length can't be present with Transfer-Encoding",
|
|
+ )
|
|
|
|
return (headers, raw_headers, close_conn, encoding, upgrade, chunked)
|
|
|
|
diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py
|
|
index 78e9ea6401..d86d238f58 100644
|
|
--- a/tests/test_http_parser.py
|
|
+++ b/tests/test_http_parser.py
|
|
@@ -291,7 +291,20 @@ def test_request_chunked(parser) -> None:
|
|
assert isinstance(payload, streams.StreamReader)
|
|
|
|
|
|
-def test_conn_upgrade(parser) -> None:
|
|
+def test_request_te_chunked_with_content_length(parser: Any) -> None:
|
|
+ text = (
|
|
+ b"GET /test HTTP/1.1\r\n"
|
|
+ b"content-length: 1234\r\n"
|
|
+ b"transfer-encoding: chunked\r\n\r\n"
|
|
+ )
|
|
+ with pytest.raises(
|
|
+ http_exceptions.BadHttpMessage,
|
|
+ match="Content-Length can't be present with Transfer-Encoding",
|
|
+ ):
|
|
+ parser.feed_data(text)
|
|
+
|
|
+
|
|
+def test_conn_upgrade(parser: Any) -> None:
|
|
text = (
|
|
b"GET /test HTTP/1.1\r\n"
|
|
b"connection: upgrade\r\n"
|