diff --git a/asgiref/typing.py b/asgiref/typing.py index c7d7576d..aff174af 100644 --- a/asgiref/typing.py +++ b/asgiref/typing.py @@ -16,6 +16,7 @@ "HTTPRequestEvent", "HTTPResponseStartEvent", "HTTPResponseBodyEvent", + "HTTPResponseTrailersEvent", "HTTPServerPushEvent", "HTTPDisconnectEvent", "WebSocketConnectEvent", @@ -99,6 +100,7 @@ class HTTPResponseStartEvent(TypedDict): type: Literal["http.response.start"] status: int headers: Iterable[Tuple[bytes, bytes]] + trailers: bool class HTTPResponseBodyEvent(TypedDict): @@ -107,6 +109,12 @@ class HTTPResponseBodyEvent(TypedDict): more_body: bool +class HTTPResponseTrailersEvent(TypedDict): + type: Literal["http.response.trailers"] + headers: Iterable[Tuple[bytes, bytes]] + more_trailers: bool + + class HTTPServerPushEvent(TypedDict): type: Literal["http.response.push"] path: str diff --git a/docs/extensions.rst b/docs/extensions.rst index 15aeb783..fecf9f03 100644 --- a/docs/extensions.rst +++ b/docs/extensions.rst @@ -167,3 +167,49 @@ The ASGI server should then attempt to send an informational response to the client with the provided links as ``Link`` headers. The server may decide to ignore this message, for example if the HTTP/1.1 protocol is used and the server has security concerns. + +HTTP Trailers +------------- + +The Trailer response header allows the sender to include additional fields at the +end of chunked messages in order to supply metadata that might be dynamically +generated while the message body is sent, such as a message integrity check, +digital signature, or post-processing status. + +ASGI servers that implement this extension will provide +``http.response.trailers`` in the extensions part of the scope:: + + "scope": { + ... + "extensions": { + "http.response.trailers": {}, + }, + } + +An ASGI framework interested in sending trailing headers to the client, must set the +field ``trailers`` in *Response Start* as ``True``. That will allow the ASGI server +to know that after the last ``http.response.body`` message (``more_body`` being ``False``), +the ASGI framework will send a ``http.response.trailers`` message. + +The ASGI framework is in charge of sending the ``Trailers`` headers to let the client know +which trailing headers the server will send. The ASGI server is not responsible for validating +the ``Trailers`` headers provided. + +Keys: + +* ``type`` (*Unicode string*): ``"http.response.trailers"`` + +* ``headers`` (*Iterable[[byte string, byte string]]*): An iterable of + ``[name, value]`` two-item iterables, where ``name`` is the header name, and + ``value`` is the header value. Header names must be lowercased. Pseudo + headers (present in HTTP/2 and HTTP/3) must not be present. + +* ``more_trailers`` (*bool*): Signifies if there is additional content + to come (as part of a *HTTP Trailers* message). If ``False``, response + will be taken as complete and closed, and any further messages on + the channel will be ignored. Optional; if missing defaults to + ``False``. + + +The ASGI server will only send the trailing headers in case the client has sent the +``TE: trailers`` header in the request. diff --git a/specs/www.rst b/specs/www.rst index eefa0d36..5f31355a 100644 --- a/specs/www.rst +++ b/specs/www.rst @@ -185,14 +185,19 @@ Keys: lowercased. Optional; if missing defaults to an empty list. Pseudo headers (present in HTTP/2 and HTTP/3) must not be present. +* ``trailers`` (*bool*) -- Signifies if the application will send + trailers. If ``True``, the server must wait until it receives a + ``"http.response.trailers"`` message after the *Response Body* event. + Optional; if missing defaults to ``False``. + Response Body - ``send`` event '''''''''''''''''''''''''''''' Continues sending a response to the client. Protocol servers must flush any data passed to them into the send buffer before returning from a -send call. If ``more_body`` is set to ``False`` this will -close the connection. +send call. If ``more_body`` is set to ``False``, and the server is not +expecting *Response Trailers* this will close the connection. Keys: @@ -203,10 +208,10 @@ Keys: missing defaults to ``b""``. * ``more_body`` (*bool*) -- Signifies if there is additional content - to come (as part of a Response Body message). If ``False``, response - will be taken as complete and closed, and any further messages on - the channel will be ignored. Optional; if missing defaults to - ``False``. + to come (as part of a *Response Body* message). If ``False``, and the + server is not expecting *Response Trailers* response will be taken as + complete and closed, and any further messages on the channel will be + ignored. Optional; if missing defaults to ``False``. Disconnect - ``receive`` event