Return the WSGI input stream, wrapped so that it may be read safely without going past the ``Content-Length`` header value or ``max_content_length``. If ``Content-Length`` exceeds ``max_content_length``, a :exc:`RequestEntityTooLarge`` ``413 Content Too Large`` error is raised. If
(
environ: WSGIEnvironment,
safe_fallback: bool = True,
max_content_length: int | None = None,
)
| 141 | |
| 142 | |
| 143 | def get_input_stream( |
| 144 | environ: WSGIEnvironment, |
| 145 | safe_fallback: bool = True, |
| 146 | max_content_length: int | None = None, |
| 147 | ) -> t.IO[bytes]: |
| 148 | """Return the WSGI input stream, wrapped so that it may be read safely without going |
| 149 | past the ``Content-Length`` header value or ``max_content_length``. |
| 150 | |
| 151 | If ``Content-Length`` exceeds ``max_content_length``, a |
| 152 | :exc:`RequestEntityTooLarge`` ``413 Content Too Large`` error is raised. |
| 153 | |
| 154 | If the WSGI server sets ``environ["wsgi.input_terminated"]``, it indicates that the |
| 155 | server handles terminating the stream, so it is safe to read directly. For example, |
| 156 | a server that knows how to handle chunked requests safely would set this. |
| 157 | |
| 158 | If ``max_content_length`` is set, it can be enforced on streams if |
| 159 | ``wsgi.input_terminated`` is set. Otherwise, an empty stream is returned unless the |
| 160 | user explicitly disables this safe fallback. |
| 161 | |
| 162 | If the limit is reached before the underlying stream is exhausted (such as a file |
| 163 | that is too large, or an infinite stream), the remaining contents of the stream |
| 164 | cannot be read safely. Depending on how the server handles this, clients may show a |
| 165 | "connection reset" failure instead of seeing the 413 response. |
| 166 | |
| 167 | :param environ: The WSGI environ containing the stream. |
| 168 | :param safe_fallback: Return an empty stream when ``Content-Length`` is not set. |
| 169 | Disabling this allows infinite streams, which can be a denial-of-service risk. |
| 170 | :param max_content_length: The maximum length that content-length or streaming |
| 171 | requests may not exceed. |
| 172 | |
| 173 | .. versionchanged:: 2.3.2 |
| 174 | ``max_content_length`` is only applied to streaming requests if the server sets |
| 175 | ``wsgi.input_terminated``. |
| 176 | |
| 177 | .. versionchanged:: 2.3 |
| 178 | Check ``max_content_length`` and raise an error if it is exceeded. |
| 179 | |
| 180 | .. versionadded:: 0.9 |
| 181 | """ |
| 182 | stream = t.cast(t.IO[bytes], environ["wsgi.input"]) |
| 183 | content_length = get_content_length(environ) |
| 184 | |
| 185 | if content_length is not None and max_content_length is not None: |
| 186 | if content_length > max_content_length: |
| 187 | raise RequestEntityTooLarge() |
| 188 | |
| 189 | # A WSGI server can set this to indicate that it terminates the input stream. In |
| 190 | # that case the stream is safe without wrapping, or can enforce a max length. |
| 191 | if "wsgi.input_terminated" in environ: |
| 192 | if max_content_length is not None: |
| 193 | # If this is moved above, it can cause the stream to hang if a read attempt |
| 194 | # is made when the client sends no data. For example, the development server |
| 195 | # does not handle buffering except for chunked encoding. |
| 196 | return t.cast( |
| 197 | t.IO[bytes], LimitedStream(stream, max_content_length, is_max=True) |
| 198 | ) |
| 199 | |
| 200 | return stream |
no test coverage detected