diff --git a/sanic/asgi.py b/sanic/asgi.py index 59d91990..9931b669 100644 --- a/sanic/asgi.py +++ b/sanic/asgi.py @@ -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({ - "type": "http.response.start", - "status": response.status, - "headers": response.processed_headers, - }) + 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 diff --git a/sanic/headers.py b/sanic/headers.py index 3dc729a9..f9a0ec3b 100644 --- a/sanic/headers.py +++ b/sanic/headers.py @@ -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, diff --git a/sanic/request.py b/sanic/request.py index 7572fa76..fb98cbae 100644 --- a/sanic/request.py +++ b/sanic/request.py @@ -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) diff --git a/sanic/response.py b/sanic/response.py index 78df7afe..9f27bcd2 100644 --- a/sanic/response.py +++ b/sanic/response.py @@ -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") diff --git a/tests/test_response.py b/tests/test_response.py index b2d5a157..34ed13ec 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -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