From d9402fc0c03353b6d2659297682e578d695476ce Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Sat, 29 Nov 2014 08:58:50 -0800 Subject: [PATCH] Make `jsonify` terminate responses with a newline This came up in the context of https://github.com/kennethreitz/httpbin/issues/168 --- CHANGES | 6 +++++- flask/json.py | 13 +++++++++---- tests/test_basic.py | 6 +++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 654ef87aa2..3c267dfafa 100644 --- a/CHANGES +++ b/CHANGES @@ -53,7 +53,11 @@ Version 1.0 - Add "pretty" and "compressed" separators definitions in jsonify() method. Reduces JSON response size when JSONIFY_PRETTYPRINT_REGULAR=False by removing unnecessary white space included by default after separators. - +- JSON responses are now terminated with a newline character, because it is a + convention that UNIX text files end with a newline and some clients don't + deal well when this newline is missing. See + https://github.com/mitsuhiko/flask/pull/1262 -- this came up originally as a + part of https://github.com/kennethreitz/httpbin/issues/168 Version 0.10.2 -------------- diff --git a/flask/json.py b/flask/json.py index a525052150..b554b9ffaa 100644 --- a/flask/json.py +++ b/flask/json.py @@ -200,8 +200,9 @@ def htmlsafe_dump(obj, fp, **kwargs): def jsonify(*args, **kwargs): """Creates a :class:`~flask.Response` with the JSON representation of - the given arguments with an :mimetype:`application/json` mimetype. The arguments - to this function are the same as to the :class:`dict` constructor. + the given arguments with an :mimetype:`application/json` mimetype. The + arguments to this function are the same as to the :class:`dict` + constructor. Example usage:: @@ -241,9 +242,13 @@ def get_current_user(): indent = 2 separators = (', ', ': ') - return current_app.response_class(dumps(dict(*args, **kwargs), - indent=indent, separators=separators), + # Note that we add '\n' to end of response + # (see https://github.com/mitsuhiko/flask/pull/1262) + rv = current_app.response_class( + (dumps(dict(*args, **kwargs), indent=indent, separators=separators), + '\n'), mimetype='application/json') + return rv def tojson_filter(obj, **kwargs): diff --git a/tests/test_basic.py b/tests/test_basic.py index 2f024a5dbc..e214aee79b 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -942,7 +942,7 @@ def test_make_response_with_response_instance(): rv = flask.make_response( flask.jsonify({'msg': 'W00t'}), 400) assert rv.status_code == 400 - assert rv.data == b'{\n "msg": "W00t"\n}' + assert rv.data == b'{\n "msg": "W00t"\n}\n' assert rv.mimetype == 'application/json' rv = flask.make_response( @@ -963,7 +963,7 @@ def test_jsonify_no_prettyprint(): app = flask.Flask(__name__) app.config.update({"JSONIFY_PRETTYPRINT_REGULAR": False}) with app.test_request_context(): - compressed_msg = b'{"msg":{"submsg":"W00t"},"msg2":"foobar"}' + compressed_msg = b'{"msg":{"submsg":"W00t"},"msg2":"foobar"}\n' uncompressed_msg = { "msg": { "submsg": "W00t" @@ -982,7 +982,7 @@ def test_jsonify_prettyprint(): with app.test_request_context(): compressed_msg = {"msg":{"submsg":"W00t"},"msg2":"foobar"} pretty_response =\ - b'{\n "msg": {\n "submsg": "W00t"\n }, \n "msg2": "foobar"\n}' + b'{\n "msg": {\n "submsg": "W00t"\n }, \n "msg2": "foobar"\n}\n' rv = flask.make_response( flask.jsonify(compressed_msg), 200)