]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/werkzeug/wrappers/request.py
1 from __future__
import annotations
8 from .._internal
import _wsgi_decoding_dance
9 from ..datastructures
import CombinedMultiDict
10 from ..datastructures
import EnvironHeaders
11 from ..datastructures
import FileStorage
12 from ..datastructures
import ImmutableMultiDict
13 from ..datastructures
import iter_multi_items
14 from ..datastructures
import MultiDict
15 from ..exceptions
import BadRequest
16 from ..exceptions
import UnsupportedMediaType
17 from ..formparser
import default_stream_factory
18 from ..formparser
import FormDataParser
19 from ..sansio
.request
import Request
as _SansIORequest
20 from ..utils
import cached_property
21 from ..utils
import environ_property
22 from ..wsgi
import _get_server
23 from ..wsgi
import get_input_stream
26 from _typeshed
.wsgi
import WSGIApplication
27 from _typeshed
.wsgi
import WSGIEnvironment
30 class Request(_SansIORequest
):
31 """Represents an incoming WSGI HTTP request, with headers and body
32 taken from the WSGI environment. Has properties and methods for
33 using the functionality defined by various HTTP specs. The data in
34 requests object is read-only.
36 Text data is assumed to use UTF-8 encoding, which should be true for
37 the vast majority of modern clients. Using an encoding set by the
38 client is unsafe in Python due to extra encodings it provides, such
39 as ``zip``. To change the assumed encoding, subclass and replace
42 :param environ: The WSGI environ is generated by the WSGI server and
43 contains information about the server configuration and client
45 :param populate_request: Add this request object to the WSGI environ
46 as ``environ['werkzeug.request']``. Can be useful when
48 :param shallow: Makes reading from :attr:`stream` (and any method
49 that would read from it) raise a :exc:`RuntimeError`. Useful to
50 prevent consuming the form data in middleware, which would make
51 it unavailable to the final application.
53 .. versionchanged:: 3.0
54 The ``charset``, ``url_charset``, and ``encoding_errors`` parameters
57 .. versionchanged:: 2.1
58 Old ``BaseRequest`` and mixin classes were removed.
60 .. versionchanged:: 2.1
61 Remove the ``disable_data_descriptor`` attribute.
63 .. versionchanged:: 2.0
64 Combine ``BaseRequest`` and mixins into a single ``Request``
67 .. versionchanged:: 0.5
68 Read-only mode is enforced with immutable classes for all data.
71 #: the maximum content length. This is forwarded to the form data
72 #: parsing function (:func:`parse_form_data`). When set and the
73 #: :attr:`form` or :attr:`files` attribute is accessed and the
74 #: parsing fails because more than the specified value is transmitted
75 #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised.
77 #: .. versionadded:: 0.5
78 max_content_length
: int |
None = None
80 #: the maximum form field size. This is forwarded to the form data
81 #: parsing function (:func:`parse_form_data`). When set and the
82 #: :attr:`form` or :attr:`files` attribute is accessed and the
83 #: data in memory for post data is longer than the specified value a
84 #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised.
86 #: .. versionadded:: 0.5
87 max_form_memory_size
: int |
None = None
89 #: The maximum number of multipart parts to parse, passed to
90 #: :attr:`form_data_parser_class`. Parsing form data with more than this
91 #: many parts will raise :exc:`~.RequestEntityTooLarge`.
93 #: .. versionadded:: 2.2.3
96 #: The form data parser that should be used. Can be replaced to customize
97 #: the form date parsing.
98 form_data_parser_class
: type[FormDataParser
] = FormDataParser
100 #: The WSGI environment containing HTTP headers and information from
102 environ
: WSGIEnvironment
104 #: Set when creating the request object. If ``True``, reading from
105 #: the request body will cause a ``RuntimeException``. Useful to
106 #: prevent modifying the stream from middleware.
111 environ
: WSGIEnvironment
,
112 populate_request
: bool = True,
113 shallow
: bool = False,
116 method
=environ
.get("REQUEST_METHOD", "GET"),
117 scheme
=environ
.get("wsgi.url_scheme", "http"),
118 server
=_get_server(environ
),
119 root_path
=_wsgi_decoding_dance(environ
.get("SCRIPT_NAME") or ""),
120 path
=_wsgi_decoding_dance(environ
.get("PATH_INFO") or ""),
121 query_string
=environ
.get("QUERY_STRING", "").encode("latin1"),
122 headers
=EnvironHeaders(environ
),
123 remote_addr
=environ
.get("REMOTE_ADDR"),
125 self
.environ
= environ
126 self
.shallow
= shallow
128 if populate_request
and not shallow
:
129 self
.environ
["werkzeug.request"] = self
132 def from_values(cls
, *args
: t
.Any
, **kwargs
: t
.Any
) -> Request
:
133 """Create a new request object based on the values provided. If
134 environ is given missing values are filled from there. This method is
135 useful for small scripts when you need to simulate a request from an URL.
136 Do not use this method for unittesting, there is a full featured client
137 object (:class:`Client`) that allows to create multipart requests,
138 support for cookies etc.
140 This accepts the same options as the
141 :class:`~werkzeug.test.EnvironBuilder`.
143 .. versionchanged:: 0.5
144 This method now accepts the same arguments as
145 :class:`~werkzeug.test.EnvironBuilder`. Because of this the
146 `environ` parameter is now called `environ_overrides`.
148 :return: request object
150 from ..test
import EnvironBuilder
152 builder
= EnvironBuilder(*args
, **kwargs
)
154 return builder
.get_request(cls
)
159 def application(cls
, f
: t
.Callable
[[Request
], WSGIApplication
]) -> WSGIApplication
:
160 """Decorate a function as responder that accepts the request as
161 the last argument. This works like the :func:`responder`
162 decorator but the function is passed the request object as the
163 last argument and the request object will be closed
167 def my_wsgi_app(request):
168 return Response('Hello World!')
170 As of Werkzeug 0.14 HTTP exceptions are automatically caught and
171 converted to responses instead of failing.
173 :param f: the WSGI callable to decorate
174 :return: a new WSGI callable
176 #: return a callable that wraps the -2nd argument with the request
177 #: and calls the function with all the arguments up to that one and
178 #: the request. The return value is then called with the latest
179 #: two arguments. This makes it possible to use this decorator for
180 #: both standalone WSGI functions as well as bound methods and
181 #: partially applied functions.
182 from ..exceptions
import HTTPException
185 def application(*args
): # type: ignore
186 request
= cls(args
[-2])
189 resp
= f(*args
[:-2] + (request
,))
190 except HTTPException
as e
:
191 resp
= e
.get_response(args
[-2])
192 return resp(*args
[-2:])
194 return t
.cast("WSGIApplication", application
)
196 def _get_file_stream(
198 total_content_length
: int |
None,
199 content_type
: str |
None,
200 filename
: str |
None = None,
201 content_length
: int |
None = None,
203 """Called to get a stream for the file upload.
205 This must provide a file-like class with `read()`, `readline()`
206 and `seek()` methods that is both writeable and readable.
208 The default implementation returns a temporary file if the total
209 content length is higher than 500KB. Because many browsers do not
210 provide a content length for the files only the total content
213 :param total_content_length: the total content length of all the
214 data in the request combined. This value
215 is guaranteed to be there.
216 :param content_type: the mimetype of the uploaded file.
217 :param filename: the filename of the uploaded file. May be `None`.
218 :param content_length: the length of this file. This value is usually
219 not provided because webbrowsers do not provide
222 return default_stream_factory(
223 total_content_length
=total_content_length
,
225 content_type
=content_type
,
226 content_length
=content_length
,
230 def want_form_data_parsed(self
) -> bool:
231 """``True`` if the request method carries content. By default
232 this is true if a ``Content-Type`` is sent.
234 .. versionadded:: 0.8
236 return bool(self
.environ
.get("CONTENT_TYPE"))
238 def make_form_data_parser(self
) -> FormDataParser
:
239 """Creates the form data parser. Instantiates the
240 :attr:`form_data_parser_class` with some parameters.
242 .. versionadded:: 0.8
244 return self
.form_data_parser_class(
245 stream_factory
=self
._get
_file
_stream
,
246 max_form_memory_size
=self
.max_form_memory_size
,
247 max_content_length
=self
.max_content_length
,
248 max_form_parts
=self
.max_form_parts
,
249 cls
=self
.parameter_storage_class
,
252 def _load_form_data(self
) -> None:
253 """Method used internally to retrieve submitted data. After calling
254 this sets `form` and `files` on the request object to multi dicts
255 filled with the incoming form data. As a matter of fact the input
256 stream will be empty afterwards. You can also call this method to
257 force the parsing of the form data.
259 .. versionadded:: 0.8
261 # abort early if we have already consumed the stream
262 if "form" in self
.__dict
__:
265 if self
.want_form_data_parsed
:
266 parser
= self
.make_form_data_parser()
268 self
._get
_stream
_for
_parsing
(),
271 self
.mimetype_params
,
276 self
.parameter_storage_class(),
277 self
.parameter_storage_class(),
280 # inject the values into the instance dict so that we bypass
281 # our cached_property non-data descriptor.
283 d
["stream"], d
["form"], d
["files"] = data
285 def _get_stream_for_parsing(self
) -> t
.IO
[bytes]:
286 """This is the same as accessing :attr:`stream` with the difference
287 that if it finds cached data from calling :meth:`get_data` first it
288 will create a new stream out of the cached data.
290 .. versionadded:: 0.9.3
292 cached_data
= getattr(self
, "_cached_data", None)
293 if cached_data
is not None:
294 return BytesIO(cached_data
)
297 def close(self
) -> None:
298 """Closes associated resources of this request object. This
299 closes all file handles explicitly. You can also use the request
300 object in a with statement which will automatically close it.
302 .. versionadded:: 0.9
304 files
= self
.__dict
__.get("files")
305 for _key
, value
in iter_multi_items(files
or ()):
308 def __enter__(self
) -> Request
:
311 def __exit__(self
, exc_type
, exc_value
, tb
) -> None: # type: ignore
315 def stream(self
) -> t
.IO
[bytes]:
316 """The WSGI input stream, with safety checks. This stream can only be consumed
319 Use :meth:`get_data` to get the full data as bytes or text. The :attr:`data`
320 attribute will contain the full bytes only if they do not represent form data.
321 The :attr:`form` attribute will contain the parsed form data in that case.
323 Unlike :attr:`input_stream`, this stream guards against infinite streams or
324 reading past :attr:`content_length` or :attr:`max_content_length`.
326 If ``max_content_length`` is set, it can be enforced on streams if
327 ``wsgi.input_terminated`` is set. Otherwise, an empty stream is returned.
329 If the limit is reached before the underlying stream is exhausted (such as a
330 file that is too large, or an infinite stream), the remaining contents of the
331 stream cannot be read safely. Depending on how the server handles this, clients
332 may show a "connection reset" failure instead of seeing the 413 response.
334 .. versionchanged:: 2.3
335 Check ``max_content_length`` preemptively and while reading.
337 .. versionchanged:: 0.9
338 The stream is always set (but may be consumed) even if form parsing was
343 "This request was created with 'shallow=True', reading"
344 " from the input stream is disabled."
347 return get_input_stream(
348 self
.environ
, max_content_length
=self
.max_content_length
351 input_stream
= environ_property
[t
.IO
[bytes]](
353 doc
="""The raw WSGI input stream, without any safety checks.
355 This is dangerous to use. It does not guard against infinite streams or reading
356 past :attr:`content_length` or :attr:`max_content_length`.
358 Use :attr:`stream` instead.
363 def data(self
) -> bytes:
364 """The raw data read from :attr:`stream`. Will be empty if the request
365 represents form data.
367 To get the raw data even if it represents form data, use :meth:`get_data`.
369 return self
.get_data(parse_form_data
=True)
372 def get_data( # type: ignore
375 as_text
: t
.Literal
[False] = False,
376 parse_form_data
: bool = False,
384 as_text
: t
.Literal
[True] = ...,
385 parse_form_data
: bool = False,
390 self
, cache
: bool = True, as_text
: bool = False, parse_form_data
: bool = False
392 """This reads the buffered incoming data from the client into one
393 bytes object. By default this is cached but that behavior can be
394 changed by setting `cache` to `False`.
396 Usually it's a bad idea to call this method without checking the
397 content length first as a client could send dozens of megabytes or more
398 to cause memory problems on the server.
400 Note that if the form data was already parsed this method will not
401 return anything as form data parsing does not cache the data like
402 this method does. To implicitly invoke form data parsing function
403 set `parse_form_data` to `True`. When this is done the return value
404 of this method will be an empty string if the form parser handles
405 the data. This generally is not necessary as if the whole data is
406 cached (which is the default) the form parser will used the cached
407 data to parse the form data. Please be generally aware of checking
408 the content length first in any case before calling this method
409 to avoid exhausting server memory.
411 If `as_text` is set to `True` the return value will be a decoded
414 .. versionadded:: 0.9
416 rv
= getattr(self
, "_cached_data", None)
419 self
._load
_form
_data
()
420 rv
= self
.stream
.read()
422 self
._cached
_data
= rv
424 rv
= rv
.decode(errors
="replace")
428 def form(self
) -> ImmutableMultiDict
[str, str]:
429 """The form parameters. By default an
430 :class:`~werkzeug.datastructures.ImmutableMultiDict`
431 is returned from this function. This can be changed by setting
432 :attr:`parameter_storage_class` to a different type. This might
433 be necessary if the order of the form data is important.
435 Please keep in mind that file uploads will not end up here, but instead
436 in the :attr:`files` attribute.
438 .. versionchanged:: 0.9
440 Previous to Werkzeug 0.9 this would only contain form data for POST
443 self
._load
_form
_data
()
447 def values(self
) -> CombinedMultiDict
[str, str]:
448 """A :class:`werkzeug.datastructures.CombinedMultiDict` that
449 combines :attr:`args` and :attr:`form`.
451 For GET requests, only ``args`` are present, not ``form``.
453 .. versionchanged:: 2.0
454 For GET requests, only ``args`` are present, not ``form``.
456 sources
= [self
.args
]
458 if self
.method
!= "GET":
459 # GET requests can have a body, and some caching proxies
460 # might not treat that differently than a normal GET
461 # request, allowing form data to "invisibly" affect the
462 # cache without indication in the query string / URL.
463 sources
.append(self
.form
)
468 if not isinstance(d
, MultiDict
):
473 return CombinedMultiDict(args
)
476 def files(self
) -> ImmutableMultiDict
[str, FileStorage
]:
477 """:class:`~werkzeug.datastructures.MultiDict` object containing
478 all uploaded files. Each key in :attr:`files` is the name from the
479 ``<input type="file" name="">``. Each value in :attr:`files` is a
480 Werkzeug :class:`~werkzeug.datastructures.FileStorage` object.
482 It basically behaves like a standard file object you know from Python,
483 with the difference that it also has a
484 :meth:`~werkzeug.datastructures.FileStorage.save` function that can
485 store the file on the filesystem.
487 Note that :attr:`files` will only contain data if the request method was
488 POST, PUT or PATCH and the ``<form>`` that posted to the request had
489 ``enctype="multipart/form-data"``. It will be empty otherwise.
491 See the :class:`~werkzeug.datastructures.MultiDict` /
492 :class:`~werkzeug.datastructures.FileStorage` documentation for
493 more details about the used data structure.
495 self
._load
_form
_data
()
499 def script_root(self
) -> str:
500 """Alias for :attr:`self.root_path`. ``environ["SCRIPT_ROOT"]``
501 without a trailing slash.
503 return self
.root_path
506 def url_root(self
) -> str:
507 """Alias for :attr:`root_url`. The URL with scheme, host, and
508 root path. For example, ``https://example.com/app/``.
512 remote_user
= environ_property
[str](
514 doc
="""If the server supports user authentication, and the
515 script is protected, this attribute contains the username the
516 user has authenticated as.""",
518 is_multithread
= environ_property
[bool](
520 doc
="""boolean that is `True` if the application is served by a
521 multithreaded WSGI server.""",
523 is_multiprocess
= environ_property
[bool](
525 doc
="""boolean that is `True` if the application is served by a
526 WSGI server that spawns multiple processes.""",
528 is_run_once
= environ_property
[bool](
530 doc
="""boolean that is `True` if the application will be
531 executed only once in a process lifetime. This is the case for
532 CGI for example, but it's not guaranteed that the execution only
533 happens one time.""",
538 #: A module or other object that has ``dumps`` and ``loads``
539 #: functions that match the API of the built-in :mod:`json` module.
543 def json(self
) -> t
.Any |
None:
544 """The parsed JSON data if :attr:`mimetype` indicates JSON
545 (:mimetype:`application/json`, see :attr:`is_json`).
547 Calls :meth:`get_json` with default arguments.
549 If the request content type is not ``application/json``, this
550 will raise a 415 Unsupported Media Type error.
552 .. versionchanged:: 2.3
553 Raise a 415 error instead of 400.
555 .. versionchanged:: 2.1
556 Raise a 400 error if the content type is incorrect.
558 return self
.get_json()
560 # Cached values for ``(silent=False, silent=True)``. Initialized
561 # with sentinel values.
562 _cached_json
: tuple[t
.Any
, t
.Any
] = (Ellipsis, Ellipsis)
566 self
, force
: bool = ..., silent
: t
.Literal
[False] = ..., cache
: bool = ...
572 self
, force
: bool = ..., silent
: bool = ..., cache
: bool = ...
577 self
, force
: bool = False, silent
: bool = False, cache
: bool = True
579 """Parse :attr:`data` as JSON.
581 If the mimetype does not indicate JSON
582 (:mimetype:`application/json`, see :attr:`is_json`), or parsing
583 fails, :meth:`on_json_loading_failed` is called and
584 its return value is used as the return value. By default this
585 raises a 415 Unsupported Media Type resp.
587 :param force: Ignore the mimetype and always try to parse JSON.
588 :param silent: Silence mimetype and parsing errors, and
589 return ``None`` instead.
590 :param cache: Store the parsed JSON to return for subsequent
593 .. versionchanged:: 2.3
594 Raise a 415 error instead of 400.
596 .. versionchanged:: 2.1
597 Raise a 400 error if the content type is incorrect.
599 if cache
and self
._cached
_json
[silent
] is not Ellipsis:
600 return self
._cached
_json
[silent
]
602 if not (force
or self
.is_json
):
604 return self
.on_json_loading_failed(None)
608 data
= self
.get_data(cache
=cache
)
611 rv
= self
.json_module
.loads(data
)
612 except ValueError as e
:
617 normal_rv
, _
= self
._cached
_json
618 self
._cached
_json
= (normal_rv
, rv
)
620 rv
= self
.on_json_loading_failed(e
)
623 _
, silent_rv
= self
._cached
_json
624 self
._cached
_json
= (rv
, silent_rv
)
627 self
._cached
_json
= (rv
, rv
)
631 def on_json_loading_failed(self
, e
: ValueError |
None) -> t
.Any
:
632 """Called if :meth:`get_json` fails and isn't silenced.
634 If this method returns a value, it is used as the return value
635 for :meth:`get_json`. The default implementation raises
636 :exc:`~werkzeug.exceptions.BadRequest`.
638 :param e: If parsing failed, this is the exception. It will be
639 ``None`` if the content type wasn't ``application/json``.
641 .. versionchanged:: 2.3
642 Raise a 415 error instead of 400.
645 raise BadRequest(f
"Failed to decode JSON object: {e}")
647 raise UnsupportedMediaType(
648 "Did not attempt to load JSON data because the request"
649 " Content-Type was not 'application/json'."