done
This commit is contained in:
257
lib/python3.11/site-packages/flask/wrappers.py
Normal file
257
lib/python3.11/site-packages/flask/wrappers.py
Normal file
@ -0,0 +1,257 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import typing as t
|
||||
|
||||
from werkzeug.exceptions import BadRequest
|
||||
from werkzeug.exceptions import HTTPException
|
||||
from werkzeug.wrappers import Request as RequestBase
|
||||
from werkzeug.wrappers import Response as ResponseBase
|
||||
|
||||
from . import json
|
||||
from .globals import current_app
|
||||
from .helpers import _split_blueprint_path
|
||||
|
||||
if t.TYPE_CHECKING: # pragma: no cover
|
||||
from werkzeug.routing import Rule
|
||||
|
||||
|
||||
class Request(RequestBase):
|
||||
"""The request object used by default in Flask. Remembers the
|
||||
matched endpoint and view arguments.
|
||||
|
||||
It is what ends up as :class:`~flask.request`. If you want to replace
|
||||
the request object used you can subclass this and set
|
||||
:attr:`~flask.Flask.request_class` to your subclass.
|
||||
|
||||
The request object is a :class:`~werkzeug.wrappers.Request` subclass and
|
||||
provides all of the attributes Werkzeug defines plus a few Flask
|
||||
specific ones.
|
||||
"""
|
||||
|
||||
json_module: t.Any = json
|
||||
|
||||
#: The internal URL rule that matched the request. This can be
|
||||
#: useful to inspect which methods are allowed for the URL from
|
||||
#: a before/after handler (``request.url_rule.methods``) etc.
|
||||
#: Though if the request's method was invalid for the URL rule,
|
||||
#: the valid list is available in ``routing_exception.valid_methods``
|
||||
#: instead (an attribute of the Werkzeug exception
|
||||
#: :exc:`~werkzeug.exceptions.MethodNotAllowed`)
|
||||
#: because the request was never internally bound.
|
||||
#:
|
||||
#: .. versionadded:: 0.6
|
||||
url_rule: Rule | None = None
|
||||
|
||||
#: A dict of view arguments that matched the request. If an exception
|
||||
#: happened when matching, this will be ``None``.
|
||||
view_args: dict[str, t.Any] | None = None
|
||||
|
||||
#: If matching the URL failed, this is the exception that will be
|
||||
#: raised / was raised as part of the request handling. This is
|
||||
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
|
||||
#: something similar.
|
||||
routing_exception: HTTPException | None = None
|
||||
|
||||
_max_content_length: int | None = None
|
||||
_max_form_memory_size: int | None = None
|
||||
_max_form_parts: int | None = None
|
||||
|
||||
@property
|
||||
def max_content_length(self) -> int | None:
|
||||
"""The maximum number of bytes that will be read during this request. If
|
||||
this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge`
|
||||
error is raised. If it is set to ``None``, no limit is enforced at the
|
||||
Flask application level. However, if it is ``None`` and the request has
|
||||
no ``Content-Length`` header and the WSGI server does not indicate that
|
||||
it terminates the stream, then no data is read to avoid an infinite
|
||||
stream.
|
||||
|
||||
Each request defaults to the :data:`MAX_CONTENT_LENGTH` config, which
|
||||
defaults to ``None``. It can be set on a specific ``request`` to apply
|
||||
the limit to that specific view. This should be set appropriately based
|
||||
on an application's or view's specific needs.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
This can be set per-request.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
This is configurable through Flask config.
|
||||
"""
|
||||
if self._max_content_length is not None:
|
||||
return self._max_content_length
|
||||
|
||||
if not current_app:
|
||||
return super().max_content_length
|
||||
|
||||
return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return]
|
||||
|
||||
@max_content_length.setter
|
||||
def max_content_length(self, value: int | None) -> None:
|
||||
self._max_content_length = value
|
||||
|
||||
@property
|
||||
def max_form_memory_size(self) -> int | None:
|
||||
"""The maximum size in bytes any non-file form field may be in a
|
||||
``multipart/form-data`` body. If this limit is exceeded, a 413
|
||||
:exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it
|
||||
is set to ``None``, no limit is enforced at the Flask application level.
|
||||
|
||||
Each request defaults to the :data:`MAX_FORM_MEMORY_SIZE` config, which
|
||||
defaults to ``500_000``. It can be set on a specific ``request`` to
|
||||
apply the limit to that specific view. This should be set appropriately
|
||||
based on an application's or view's specific needs.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
This is configurable through Flask config.
|
||||
"""
|
||||
if self._max_form_memory_size is not None:
|
||||
return self._max_form_memory_size
|
||||
|
||||
if not current_app:
|
||||
return super().max_form_memory_size
|
||||
|
||||
return current_app.config["MAX_FORM_MEMORY_SIZE"] # type: ignore[no-any-return]
|
||||
|
||||
@max_form_memory_size.setter
|
||||
def max_form_memory_size(self, value: int | None) -> None:
|
||||
self._max_form_memory_size = value
|
||||
|
||||
@property # type: ignore[override]
|
||||
def max_form_parts(self) -> int | None:
|
||||
"""The maximum number of fields that may be present in a
|
||||
``multipart/form-data`` body. If this limit is exceeded, a 413
|
||||
:exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it
|
||||
is set to ``None``, no limit is enforced at the Flask application level.
|
||||
|
||||
Each request defaults to the :data:`MAX_FORM_PARTS` config, which
|
||||
defaults to ``1_000``. It can be set on a specific ``request`` to apply
|
||||
the limit to that specific view. This should be set appropriately based
|
||||
on an application's or view's specific needs.
|
||||
|
||||
.. versionchanged:: 3.1
|
||||
This is configurable through Flask config.
|
||||
"""
|
||||
if self._max_form_parts is not None:
|
||||
return self._max_form_parts
|
||||
|
||||
if not current_app:
|
||||
return super().max_form_parts
|
||||
|
||||
return current_app.config["MAX_FORM_PARTS"] # type: ignore[no-any-return]
|
||||
|
||||
@max_form_parts.setter
|
||||
def max_form_parts(self, value: int | None) -> None:
|
||||
self._max_form_parts = value
|
||||
|
||||
@property
|
||||
def endpoint(self) -> str | None:
|
||||
"""The endpoint that matched the request URL.
|
||||
|
||||
This will be ``None`` if matching failed or has not been
|
||||
performed yet.
|
||||
|
||||
This in combination with :attr:`view_args` can be used to
|
||||
reconstruct the same URL or a modified URL.
|
||||
"""
|
||||
if self.url_rule is not None:
|
||||
return self.url_rule.endpoint # type: ignore[no-any-return]
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def blueprint(self) -> str | None:
|
||||
"""The registered name of the current blueprint.
|
||||
|
||||
This will be ``None`` if the endpoint is not part of a
|
||||
blueprint, or if URL matching failed or has not been performed
|
||||
yet.
|
||||
|
||||
This does not necessarily match the name the blueprint was
|
||||
created with. It may have been nested, or registered with a
|
||||
different name.
|
||||
"""
|
||||
endpoint = self.endpoint
|
||||
|
||||
if endpoint is not None and "." in endpoint:
|
||||
return endpoint.rpartition(".")[0]
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def blueprints(self) -> list[str]:
|
||||
"""The registered names of the current blueprint upwards through
|
||||
parent blueprints.
|
||||
|
||||
This will be an empty list if there is no current blueprint, or
|
||||
if URL matching failed.
|
||||
|
||||
.. versionadded:: 2.0.1
|
||||
"""
|
||||
name = self.blueprint
|
||||
|
||||
if name is None:
|
||||
return []
|
||||
|
||||
return _split_blueprint_path(name)
|
||||
|
||||
def _load_form_data(self) -> None:
|
||||
super()._load_form_data()
|
||||
|
||||
# In debug mode we're replacing the files multidict with an ad-hoc
|
||||
# subclass that raises a different error for key errors.
|
||||
if (
|
||||
current_app
|
||||
and current_app.debug
|
||||
and self.mimetype != "multipart/form-data"
|
||||
and not self.files
|
||||
):
|
||||
from .debughelpers import attach_enctype_error_multidict
|
||||
|
||||
attach_enctype_error_multidict(self)
|
||||
|
||||
def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
|
||||
try:
|
||||
return super().on_json_loading_failed(e)
|
||||
except BadRequest as ebr:
|
||||
if current_app and current_app.debug:
|
||||
raise
|
||||
|
||||
raise BadRequest() from ebr
|
||||
|
||||
|
||||
class Response(ResponseBase):
|
||||
"""The response object that is used by default in Flask. Works like the
|
||||
response object from Werkzeug but is set to have an HTML mimetype by
|
||||
default. Quite often you don't have to create this object yourself because
|
||||
:meth:`~flask.Flask.make_response` will take care of that for you.
|
||||
|
||||
If you want to replace the response object used you can subclass this and
|
||||
set :attr:`~flask.Flask.response_class` to your subclass.
|
||||
|
||||
.. versionchanged:: 1.0
|
||||
JSON support is added to the response, like the request. This is useful
|
||||
when testing to get the test client response data as JSON.
|
||||
|
||||
.. versionchanged:: 1.0
|
||||
|
||||
Added :attr:`max_cookie_size`.
|
||||
"""
|
||||
|
||||
default_mimetype: str | None = "text/html"
|
||||
|
||||
json_module = json
|
||||
|
||||
autocorrect_location_header = False
|
||||
|
||||
@property
|
||||
def max_cookie_size(self) -> int: # type: ignore
|
||||
"""Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
|
||||
|
||||
See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in
|
||||
Werkzeug's docs.
|
||||
"""
|
||||
if current_app:
|
||||
return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return]
|
||||
|
||||
# return Werkzeug's default when not in an app context
|
||||
return super().max_cookie_size
|
Reference in New Issue
Block a user