1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
|
Extensions
==========
The ASGI specification provides for server-specific extensions to be
used outside of the core ASGI specification. This document specifies
some common extensions.
Websocket Denial Response
-------------------------
Websocket connections start with the client sending a HTTP request
containing the appropriate upgrade headers. On receipt of this request
a server can choose to either upgrade the connection or respond with an
HTTP response (denying the upgrade). The core ASGI specification does
not allow for any control over the denial response, instead specifying
that the HTTP status code ``403`` should be returned, whereas this
extension allows an ASGI framework to control the
denial response. Rather than being a core part of
ASGI, this is an extension for what is considered a niche feature as most
clients do not utilise the denial response.
ASGI Servers that implement this extension will provide
``websocket.http.response`` in the extensions part of the scope::
"scope": {
...
"extensions": {
"websocket.http.response": {},
},
}
This will allow the ASGI Framework to send HTTP response messages
after the ``websocket.connect`` message. These messages cannot be
followed by any other websocket messages as the server should send a
HTTP response and then close the connection.
The messages themselves should be ``websocket.http.response.start``
and ``websocket.http.response.body`` with a structure that matches the
``http.response.start`` and ``http.response.body`` messages defined in
the HTTP part of the core ASGI specification.
HTTP/2 Server Push
------------------
HTTP/2 allows for a server to push a resource to a client by sending a
push promise. ASGI servers that implement this extension will provide
``http.response.push`` in the extensions part of the scope::
"scope": {
...
"extensions": {
"http.response.push": {},
},
}
An ASGI framework can initiate a server push by sending a message with
the following keys. This message can be sent at any time after the
*Response Start* message but before the final *Response Body* message.
Keys:
* ``type`` (*Unicode string*): ``"http.response.push"``
* ``path`` (*Unicode string*): HTTP path from URL, with percent-encoded
sequences and UTF-8 byte sequences decoded into characters.
* ``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.
The ASGI server should then attempt to send a server push (or push
promise) to the client. If the client supports server push, the server
should create a new connection to a new instance of the application
and treat it as if the client had made a request.
The ASGI server should set the pseudo ``:authority`` header value to
be the same value as the request that triggered the push promise.
Zero Copy Send
--------------
Zero Copy Send allows you to send the contents of a file descriptor to the
HTTP client with zero copy (where the underlying OS directly handles the data
transfer from a source file or socket without loading it into Python and
writing it out again).
ASGI servers that implement this extension will provide
``http.response.zerocopysend`` in the extensions part of the scope::
"scope": {
...
"extensions": {
"http.response.zerocopysend": {},
},
}
The ASGI framework can initiate a zero-copy send by sending a message with
the following keys. This message can be sent at any time after the
*Response Start* message but before the final *Response Body* message,
and can be mixed with ``http.response.body``. It can also be called
multiple times in one response. Except for the characteristics of
zero-copy, it should behave the same as ordinary ``http.response.body``.
Keys:
* ``type`` (*Unicode string*): ``"http.response.zerocopysend"``
* ``file`` (*file descriptor object*): An opened file descriptor object
with an underlying OS file descriptor that can be used to call
``os.sendfile``. (e.g. not BytesIO)
* ``offset`` (*int*): Optional. If this value exists, it will specify
the offset at which sendfile starts to read data from ``file``.
Otherwise, it will be read from the current position of ``file``.
* ``count`` (*int*): Optional. ``count`` is the number of bytes to
copy between the file descriptors. If omitted, the file will be read until
its end.
* ``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``.
After calling this extension to respond, the ASGI application itself should
actively close the used file descriptor - ASGI servers are not responsible for
closing descriptors.
Path Send
---------
Path Send allows you to send the contents of a file path to the
HTTP client without handling file descriptors, offloading the operation
directly to the server.
ASGI servers that implement this extension will provide
``http.response.pathsend`` in the extensions part of the scope::
"scope": {
...
"extensions": {
"http.response.pathsend": {},
},
}
The ASGI framework can initiate a path-send by sending a message with
the following keys. This message can be sent at any time after the
*Response Start* message, and cannot be mixed with ``http.response.body``.
It can be called just one time in one response.
Except for the characteristics of path-send, it should behave the same
as ordinary ``http.response.body``.
Keys:
* ``type`` (*Unicode string*): ``"http.response.pathsend"``
* ``path`` (*Unicode string*): The string representation of the absolute
file path to be sent by the server, platform specific.
The ASGI application itself is responsible to send the relevant headers
in the *Response Start* message, like the ``Content-Type`` and
``Content-Length`` headers for the file to be sent.
TLS
---
See :doc:`specs/tls`.
Early Hints
-----------
An informational response with the status code 103 is an Early Hint,
indicating to the client that resources are associated with the
subsequent response, see ``RFC 8297``. ASGI servers that implement
this extension will allow early hints to be sent. These servers will
provide ``http.response.early_hint`` in the extensions part of the
scope::
"scope": {
...
"extensions": {
"http.response.early_hint": {},
},
}
An ASGI framework can send an early hint by sending a message with the
following keys. This message can be sent at any time (and multiple
times) after the *Response Start* message but before the final
*Response Body* message.
Keys:
* ``type`` (*Unicode string*): ``"http.response.early_hint"``
* ``links`` (*Iterable[byte string]*): An iterable of link header field
values, see ``RFC 8288``.
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.
Debug
-----
The debug extension allows a way to send debug information from an ASGI framework in
its responses. This extension is not meant to be used in production, only for testing purposes,
and ASGI servers should not implement it.
The ASGI context sent to the framework will provide ``http.response.debug`` in the extensions
part of the scope::
"scope": {
...
"extensions": {
"http.response.debug": {},
},
}
The ASGI framework can send debug information by sending a message with the following
keys. This message must be sent once, before the *Response Start* message.
Keys:
* ``type`` (*Unicode string*): ``"http.response.debug"``
* ``info`` (*Dict[Unicode string, Any]*): A dictionary containing the debug information.
The keys and values of this dictionary are not defined by the ASGI specification, and
are left to the ASGI framework to define.
|