format_http1_response
This commit is contained in:
parent
d248dbb72b
commit
7dc683913f
|
@ -3,6 +3,8 @@ import re
|
|||
from typing import Any, Dict, Iterable, Optional, Tuple
|
||||
from urllib.parse import unquote
|
||||
|
||||
from sanic.helpers import STATUS_CODES
|
||||
|
||||
|
||||
HeaderIterable = Iterable[Tuple[str, Any]] # Values convertible to str
|
||||
Options = Dict[str, str] # key=value fields in various headers
|
||||
|
@ -175,3 +177,21 @@ def format_http1(headers: HeaderIterable) -> bytes:
|
|||
- Values are converted into strings if necessary.
|
||||
"""
|
||||
return "".join(f"{name}: {val}\r\n" for name, val in headers).encode()
|
||||
|
||||
|
||||
def format_http1_response(
|
||||
status: int, headers: HeaderIterable, body=b""
|
||||
) -> bytes:
|
||||
"""Format a full HTTP/1.1 response.
|
||||
|
||||
- If `body` is included, content-length must be specified in headers.
|
||||
"""
|
||||
headers = format_http1(headers)
|
||||
if status == 200:
|
||||
return b"HTTP/1.1 200 OK\r\n%b\r\n%b" % (headers, body)
|
||||
return b"HTTP/1.1 %d %b\r\n%b\r\n%b" % (
|
||||
status,
|
||||
STATUS_CODES.get(status, b"UNKNOWN"),
|
||||
headers,
|
||||
body,
|
||||
)
|
||||
|
|
|
@ -7,8 +7,8 @@ from aiofiles import open as open_async
|
|||
|
||||
from sanic.compat import Header
|
||||
from sanic.cookies import CookieJar
|
||||
from sanic.headers import format_http1
|
||||
from sanic.helpers import STATUS_CODES, has_message_body, remove_entity_headers
|
||||
from sanic.headers import format_http1, format_http1_response
|
||||
from sanic.helpers import has_message_body, remove_entity_headers
|
||||
|
||||
|
||||
try:
|
||||
|
@ -104,33 +104,17 @@ class StreamingHTTPResponse(BaseHTTPResponse):
|
|||
def get_headers(
|
||||
self, version="1.1", keep_alive=False, keep_alive_timeout=None
|
||||
):
|
||||
# This is all returned in a kind-of funky way
|
||||
# We tried to make this as fast as possible in pure python
|
||||
timeout_header = b""
|
||||
if "Content-Type" not in self.headers:
|
||||
self.headers["Content-Type"] = self.content_type
|
||||
|
||||
if keep_alive and keep_alive_timeout is not None:
|
||||
timeout_header = b"Keep-Alive: %d\r\n" % keep_alive_timeout
|
||||
self.headers["Keep-Alive"] = keep_alive_timeout
|
||||
|
||||
if self.chunked and version == "1.1":
|
||||
self.headers["Transfer-Encoding"] = "chunked"
|
||||
self.headers.pop("Content-Length", None)
|
||||
self.headers["Content-Type"] = self.headers.get(
|
||||
"Content-Type", self.content_type
|
||||
)
|
||||
|
||||
headers = self._parse_headers()
|
||||
|
||||
if self.status == 200:
|
||||
status = b"OK"
|
||||
else:
|
||||
status = STATUS_CODES.get(self.status)
|
||||
|
||||
return (b"HTTP/%b %d %b\r\n" b"%b" b"%b\r\n") % (
|
||||
version.encode(),
|
||||
self.status,
|
||||
status,
|
||||
timeout_header,
|
||||
headers,
|
||||
)
|
||||
return format_http1_response(self.status, self.headers.items())
|
||||
|
||||
|
||||
class HTTPResponse(BaseHTTPResponse):
|
||||
|
@ -156,11 +140,8 @@ class HTTPResponse(BaseHTTPResponse):
|
|||
self._cookies = None
|
||||
|
||||
def output(self, version="1.1", keep_alive=False, keep_alive_timeout=None):
|
||||
# This is all returned in a kind-of funky way
|
||||
# We tried to make this as fast as possible in pure python
|
||||
timeout_header = b""
|
||||
if keep_alive and keep_alive_timeout is not None:
|
||||
timeout_header = b"Keep-Alive: %d\r\n" % keep_alive_timeout
|
||||
if "Content-Type" not in self.headers:
|
||||
self.headers["Content-Type"] = self.content_type
|
||||
|
||||
body = b""
|
||||
if has_message_body(self.status):
|
||||
|
@ -176,24 +157,13 @@ class HTTPResponse(BaseHTTPResponse):
|
|||
if self.status in (304, 412):
|
||||
self.headers = remove_entity_headers(self.headers)
|
||||
|
||||
headers = self._parse_headers()
|
||||
if keep_alive and keep_alive_timeout is not None:
|
||||
self.headers["Connection"] = "keep-alive"
|
||||
self.headers["Keep-Alive"] = keep_alive_timeout
|
||||
elif not keep_alive:
|
||||
self.headers["Connection"] = "close"
|
||||
|
||||
if self.status == 200:
|
||||
status = b"OK"
|
||||
else:
|
||||
status = STATUS_CODES.get(self.status, b"UNKNOWN RESPONSE")
|
||||
|
||||
return (
|
||||
b"HTTP/%b %d %b\r\n" b"Connection: %b\r\n" b"%b" b"%b\r\n" b"%b"
|
||||
) % (
|
||||
version.encode(),
|
||||
self.status,
|
||||
status,
|
||||
b"keep-alive" if keep_alive else b"close",
|
||||
timeout_header,
|
||||
headers,
|
||||
body,
|
||||
)
|
||||
return format_http1_response(self.status, self.headers.items(), body)
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user