diff --git a/CHANGES.rst b/CHANGES.rst index 3f5a003e..185dd4d6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -145,11 +145,14 @@ unreleased (`#2635`_) - A single trailing slash is stripped from the blueprint ``url_prefix`` when it is registered with the app. (`#2629`_) -- :meth:`Request.get_json() ` doesn't cache the +- :meth:`Request.get_json` doesn't cache the result if parsing fails when ``silent`` is true. (`#2651`_) -- :func:`request.get_json ` no longer accepts - arbitrary encodings. Incoming JSON should be encoded using UTF-8 per - :rfc:`8259`, but Flask will autodetect UTF-8, -16, or -32. (`#2691`_) +- :func:`Request.get_json` no longer accepts arbitrary encodings. + Incoming JSON should be encoded using UTF-8 per :rfc:`8259`, but Flask + will autodetect UTF-8, -16, or -32. (`#2691`_) +- Added :data:`MAX_COOKIE_SIZE` and :attr:`Response.max_cookie_size` to + control when Werkzeug warns about large cookies that browsers may + ignore. (`#2693`_) .. _pallets/meta#24: https://github.com/pallets/meta/issues/24 .. _#1421: https://github.com/pallets/flask/issues/1421 @@ -196,6 +199,7 @@ unreleased .. _#2629: https://github.com/pallets/flask/pull/2629 .. _#2651: https://github.com/pallets/flask/issues/2651 .. _#2691: https://github.com/pallets/flask/pull/2691 +.. _#2693: https://github.com/pallets/flask/pull/2693 Version 0.12.2 diff --git a/docs/api.rst b/docs/api.rst index c8820218..f344478b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -85,7 +85,7 @@ Response Objects ---------------- .. autoclass:: flask.Response - :members: set_cookie, data, mimetype, is_json, get_json + :members: set_cookie, max_cookie_size, data, mimetype, is_json, get_json .. attribute:: headers diff --git a/docs/config.rst b/docs/config.rst index c496ac00..d521ab72 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -343,6 +343,12 @@ The following configuration values are used internally by Flask: Default: ``False`` +.. py:data:: MAX_COOKIE_SIZE + + Warn if cookie headers are larger than this many bytes. Defaults to + ``4093``. Larger cookies may be silently ignored by browsers. Set to + ``0`` to disable the warning. + .. versionadded:: 0.4 ``LOGGER_NAME`` @@ -381,6 +387,8 @@ The following configuration values are used internally by Flask: Added :data:`SESSION_COOKIE_SAMESITE` to control the session cookie's ``SameSite`` option. + Added :data:`MAX_COOKIE_SIZE` to control a warning from Werkzeug. + Configuring from Files ---------------------- diff --git a/flask/app.py b/flask/app.py index 22183dcc..54ed0402 100644 --- a/flask/app.py +++ b/flask/app.py @@ -305,6 +305,7 @@ class Flask(_PackageBoundObject): 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, + 'MAX_COOKIE_SIZE': 4093, }) #: The rule object to use for URL rules created. This is used by diff --git a/flask/wrappers.py b/flask/wrappers.py index 0a2bd2e4..12eff2c7 100644 --- a/flask/wrappers.py +++ b/flask/wrappers.py @@ -191,9 +191,26 @@ class Response(ResponseBase, JSONMixin): .. 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 = 'text/html' def _get_data_for_json(self, cache): return self.get_data() + + @property + def max_cookie_size(self): + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.BaseResponse.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config['MAX_COOKIE_SIZE'] + + # return Werkzeug's default when not in an app context + return super(Response, self).max_cookie_size diff --git a/tests/test_basic.py b/tests/test_basic.py index 66e0d907..9d6c58c1 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1917,3 +1917,33 @@ def test_run_from_config(monkeypatch, host, port, expect_host, expect_port, app) monkeypatch.setattr(werkzeug.serving, 'run_simple', run_simple_mock) app.config['SERVER_NAME'] = 'pocoo.org:8080' app.run(host, port) + + +def test_max_cookie_size(app, client, recwarn): + app.config['MAX_COOKIE_SIZE'] = 100 + + # outside app context, default to Werkzeug static value, + # which is also the default config + response = flask.Response() + default = flask.Flask.default_config['MAX_COOKIE_SIZE'] + assert response.max_cookie_size == default + + # inside app context, use app config + with app.app_context(): + assert flask.Response().max_cookie_size == 100 + + @app.route('/') + def index(): + r = flask.Response('', status=204) + r.set_cookie('foo', 'bar' * 100) + return r + + client.get('/') + assert len(recwarn) == 1 + w = recwarn.pop() + assert 'cookie is too large' in str(w.message) + + app.config['MAX_COOKIE_SIZE'] = 0 + + client.get('/') + assert len(recwarn) == 0