From 1e8419bde47ff5a287d054084e70ae0632a14456 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sun, 23 Jun 2019 12:52:10 -0700 Subject: [PATCH] Use correct content-type header, refs #272 --- datasette/renderer.py | 2 +- datasette/utils/asgi.py | 7 +++++-- datasette/views/index.py | 2 +- datasette/views/special.py | 4 +++- tests/test_api.py | 1 + tests/test_html.py | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/datasette/renderer.py b/datasette/renderer.py index 417fecb5..349c2922 100644 --- a/datasette/renderer.py +++ b/datasette/renderer.py @@ -88,5 +88,5 @@ def json_renderer(args, data, view_name): content_type = "text/plain" else: body = json.dumps(data, cls=CustomJSONEncoder) - content_type = "application/json" + content_type = "application/json; charset=utf-8" return {"body": body, "status_code": status_code, "content_type": content_type} diff --git a/datasette/utils/asgi.py b/datasette/utils/asgi.py index c7afa21c..2ae8ab6e 100644 --- a/datasette/utils/asgi.py +++ b/datasette/utils/asgi.py @@ -90,13 +90,16 @@ class AsgiView(HTTPMethodView): if hasattr(response, "asgi_send"): await response.asgi_send(send) else: + headers = {} + headers.update(response.headers) + headers["content-type"] = response.content_type await send( { "type": "http.response.start", "status": response.status, "headers": [ [key.encode("utf-8"), value.encode("utf-8")] - for key, value in response.headers.items() + for key, value in headers.items() ], } ) @@ -158,7 +161,7 @@ async def asgi_send_json(send, info, status=200, headers=None): json.dumps(info), status=status, headers=headers, - content_type="application/json", + content_type="application/json; charset=utf-8", ) diff --git a/datasette/views/index.py b/datasette/views/index.py index c9d15c36..c01ae811 100644 --- a/datasette/views/index.py +++ b/datasette/views/index.py @@ -106,7 +106,7 @@ class IndexView(BaseView): headers["Access-Control-Allow-Origin"] = "*" return response.HTTPResponse( json.dumps({db["name"]: db for db in databases}, cls=CustomJSONEncoder), - content_type="application/json", + content_type="application/json; charset=utf-8", headers=headers, ) else: diff --git a/datasette/views/special.py b/datasette/views/special.py index 91b577fc..1e0c2032 100644 --- a/datasette/views/special.py +++ b/datasette/views/special.py @@ -18,7 +18,9 @@ class JsonDataView(BaseView): if self.ds.cors: headers["Access-Control-Allow-Origin"] = "*" return response.HTTPResponse( - json.dumps(data), content_type="application/json", headers=headers + json.dumps(data), + content_type="application/json; charset=utf-8", + headers=headers, ) else: diff --git a/tests/test_api.py b/tests/test_api.py index 6ed990f3..96c16175 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -22,6 +22,7 @@ import urllib def test_homepage(app_client): response = app_client.get("/.json") assert response.status == 200 + assert "application/json; charset=utf-8" == response.headers["content-type"] assert response.json.keys() == {"fixtures": 0}.keys() d = response.json["fixtures"] assert d["name"] == "fixtures" diff --git a/tests/test_html.py b/tests/test_html.py index 60014691..7a5c32c4 100644 --- a/tests/test_html.py +++ b/tests/test_html.py @@ -17,6 +17,7 @@ import urllib.parse def test_homepage(app_client_two_attached_databases): response = app_client_two_attached_databases.get("/") assert response.status == 200 + assert "text/html; charset=utf-8" == response.headers["content-type"] soup = Soup(response.body, "html.parser") assert "Datasette Fixtures" == soup.find("h1").text assert (