This commit is contained in:
L. Kärkkäinen 2020-03-09 15:44:06 +02:00
parent a9d984e2f8
commit 9dc2ec966c
5 changed files with 14 additions and 20 deletions

View File

@ -6,11 +6,8 @@ from typing import (
Any,
Awaitable,
Callable,
Dict,
List,
MutableMapping,
Optional,
Tuple,
Union,
)
from urllib.parse import quote
@ -18,10 +15,8 @@ from urllib.parse import quote
import sanic.app # noqa
from sanic.compat import Header
from sanic.exceptions import InvalidUsage, ServerError
from sanic.log import logger
from sanic.exceptions import InvalidUsage
from sanic.request import Request
from sanic.response import StreamingHTTPResponse
from sanic.websocket import WebSocketConnection
@ -278,11 +273,13 @@ class ASGIApp:
async def send(self, data, end_stream):
if self.response:
response, self.response = self.response, None
await self.transport.send({
await self.transport.send(
{
"type": "http.response.start",
"status": response.status,
"headers": response.processed_headers,
})
}
)
response_body = getattr(response, "body", None)
if response_body:
data = response_body + data if data else response_body

View File

@ -175,11 +175,13 @@ def parse_host(host: str) -> Tuple[Optional[str], Optional[int]]:
host, port = m.groups()
return host.lower(), int(port) if port is not None else None
_HTTP1_STATUSLINES = [
b"HTTP/1.1 %d %b\r\n" % (status, STATUS_CODES.get(status, b"UNKNOWN"))
for status in range(1000)
]
def format_http1_response(status: int, headers: HeaderBytesIterable) -> bytes:
"""Format a HTTP/1.1 response header."""
# Note: benchmarks show that here bytes concat is faster than bytearray,

View File

@ -111,9 +111,7 @@ class Request:
# This logic of determining which response to use is subject to change
if response is None:
response = self.stream.response or HTTPResponse(
status=status,
headers=headers,
content_type=content_type,
status=status, headers=headers, content_type=content_type,
)
# Connect the response and return it
return self.stream.respond(response)

View File

@ -43,10 +43,7 @@ class BaseHTTPResponse:
self.headers.setdefault("content-type", self.content_type)
# Encode headers into bytes
return (
(
name.encode("ascii"),
f"{value}".encode("utf-8", errors="surrogateescape")
)
(name.encode("ascii"), f"{value}".encode(errors="surrogateescape"))
for name, value in self.headers.items()
)
@ -64,6 +61,7 @@ class BaseHTTPResponse:
class StreamingHTTPResponse(BaseHTTPResponse):
"""Old style streaming response. Use `request.respond()` instead of this in
new code to avoid the callback."""
__slots__ = (
"protocol",
"streaming_fn",
@ -101,7 +99,6 @@ class StreamingHTTPResponse(BaseHTTPResponse):
await super().send(*args, **kwargs)
class HTTPResponse(BaseHTTPResponse):
__slots__ = ("body", "status", "content_type", "headers", "_cookies")

View File

@ -15,6 +15,7 @@ from aiofiles import os as async_os
from sanic.response import (
HTTPResponse,
StreamingHTTPResponse,
empty,
file,
file_stream,
json,
@ -22,7 +23,6 @@ from sanic.response import (
stream,
text,
)
from sanic.response import empty
from sanic.server import HttpProtocol
from sanic.testing import HOST, PORT