Add raw header info to request object (#2032)

This commit is contained in:
Adam Hopkins
2021-03-03 16:33:34 +02:00
committed by GitHub
parent c41d7136e8
commit a733d32715
6 changed files with 57 additions and 15 deletions

View File

@@ -1 +1,2 @@
HTTP_METHODS = ("GET", "POST", "PUT", "HEAD", "OPTIONS", "PATCH", "DELETE")
DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"

View File

@@ -189,8 +189,9 @@ class Http:
# Parse header content
try:
raw_headers = buf[:pos].decode(errors="surrogateescape")
reqline, *raw_headers = raw_headers.split("\r\n")
head = buf[:pos]
raw_headers = head.decode(errors="surrogateescape")
reqline, *split_headers = raw_headers.split("\r\n")
method, self.url, protocol = reqline.split(" ")
if protocol == "HTTP/1.1":
@@ -204,7 +205,7 @@ class Http:
request_body = False
headers = []
for name, value in (h.split(":", 1) for h in raw_headers):
for name, value in (h.split(":", 1) for h in split_headers):
name, value = h = name.lower(), value.lstrip()
if name in ("content-length", "transfer-encoding"):
@@ -223,6 +224,7 @@ class Http:
request = self.protocol.request_class(
url_bytes=self.url.encode(),
headers=headers_instance,
head=bytes(head),
version=protocol[5:],
method=method,
transport=self.protocol.transport,

View File

@@ -11,7 +11,7 @@ from urllib.parse import unquote
from sanic_routing.route import Route # type: ignore
from sanic.compat import stat_async
from sanic.constants import HTTP_METHODS
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE, HTTP_METHODS
from sanic.exceptions import (
ContentRangeError,
FileNotFound,
@@ -689,7 +689,7 @@ class RouteMixin:
content_type = (
content_type
or guess_type(file_path)[0]
or "application/octet-stream"
or DEFAULT_HTTP_CONTENT_TYPE
)
if "charset=" not in content_type and (

View File

@@ -31,6 +31,7 @@ from urllib.parse import parse_qs, parse_qsl, unquote, urlunparse
from httptools import parse_url # type: ignore
from sanic.compat import CancelledErrors, Header
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
from sanic.exceptions import InvalidUsage
from sanic.headers import (
Options,
@@ -49,12 +50,6 @@ try:
except ImportError:
from json import loads as json_loads # type: ignore
DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
# HTTP/1.1: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
# > If the media type remains unknown, the recipient SHOULD treat it
# > as type "application/octet-stream"
class RequestParameters(dict):
"""
@@ -95,6 +90,7 @@ class Request:
"conn_info",
"ctx",
"endpoint",
"head",
"headers",
"method",
"name",
@@ -121,6 +117,7 @@ class Request:
method: str,
transport: TransportProtocol,
app: Sanic,
head: bytes = b"",
):
self.raw_url = url_bytes
# TODO: Content-Encoding detection
@@ -132,6 +129,7 @@ class Request:
self.version = version
self.method = method
self.transport = transport
self.head = head
# Init but do not inhale
self.body = b""
@@ -207,6 +205,16 @@ class Request:
if not self.body:
self.body = b"".join([data async for data in self.stream])
@property
def raw_headers(self):
_, headers = self.head.split(b"\r\n", 1)
return bytes(headers)
@property
def request_line(self):
reqline, _ = self.head.split(b"\r\n", 1)
return bytes(reqline)
@property
def id(self) -> Optional[Union[uuid.UUID, str, int]]:
"""

View File

@@ -17,6 +17,7 @@ from urllib.parse import quote_plus
from warnings import warn
from sanic.compat import Header, open_async
from sanic.constants import DEFAULT_HTTP_CONTENT_TYPE
from sanic.cookies import CookieJar
from sanic.helpers import has_message_body, remove_entity_headers
from sanic.http import Http
@@ -297,7 +298,7 @@ def raw(
body: Optional[AnyStr],
status: int = 200,
headers: Optional[Dict[str, str]] = None,
content_type: str = "application/octet-stream",
content_type: str = DEFAULT_HTTP_CONTENT_TYPE,
) -> HTTPResponse:
"""
Returns response object without encoding the body.