From fa8b4f2ca401eae145014986be9157701fe5aff3 Mon Sep 17 00:00:00 2001 From: Nicola Iarocci Date: Thu, 11 Oct 2018 10:49:37 +0200 Subject: [PATCH] Fix: CORS response headers missing for media endpoint Closes #1197. --- CHANGES.rst | 6 +++++- eve/endpoints.py | 5 ++++- eve/flaskapp.py | 2 +- eve/render.py | 2 ++ eve/tests/io/media.py | 27 +++++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0095c5d01..dff62afd3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,11 @@ Here you can see the full list of changes between each Eve release. Version 0.8.2 ------------- -- hic sunt leones +Fixed +~~~~~ +- CORS response headers missing for media endpoint (`#1197`_) + +.. _`#1197`: https://github.com/pyeve/eve/issues/1197 Version 0.8.1 ------------- diff --git a/eve/endpoints.py b/eve/endpoints.py index 923515300..e9f80358a 100644 --- a/eve/endpoints.py +++ b/eve/endpoints.py @@ -185,6 +185,9 @@ def media_endpoint(_id): .. versionadded:: 0.6 """ + if request.method == "OPTIONS": + return send_response(None, (None)) + file_ = app.media.get(_id) if file_ is None: return abort(404) @@ -238,7 +241,7 @@ def media_endpoint(_id): direct_passthrough=True, ) - return response + return send_response(None, (response,)) @requires_auth("resource") diff --git a/eve/flaskapp.py b/eve/flaskapp.py index 4d423cfc4..8fb953fee 100644 --- a/eve/flaskapp.py +++ b/eve/flaskapp.py @@ -1067,7 +1067,7 @@ def _init_media_endpoint(self): self.config["MEDIA_URL"], ) self.add_url_rule( - media_url, "media", view_func=media_endpoint, methods=["GET"] + media_url, "media", view_func=media_endpoint, methods=["GET", "OPTIONS"] ) def _init_schema_endpoint(self): diff --git a/eve/render.py b/eve/render.py index 44f9ad09e..882c21da9 100644 --- a/eve/render.py +++ b/eve/render.py @@ -138,6 +138,8 @@ def _prepare_response( """ if request.method == "OPTIONS": resp = app.make_default_options_response() + elif isinstance(dct, Response): + resp = dct else: # obtain the best match between client's request and available mime # types, along with the corresponding render function. diff --git a/eve/tests/io/media.py b/eve/tests/io/media.py index 2f2837405..4b5eed3ad 100644 --- a/eve/tests/io/media.py +++ b/eve/tests/io/media.py @@ -426,6 +426,33 @@ def test_gridfs_media_storage_base_url(self): url, ) + def test_media_endpoint_supports_CORS(self): + self.app._init_media_endpoint() + self.app.config["RETURN_MEDIA_AS_BASE64_STRING"] = False + self.app.config["RETURN_MEDIA_AS_URL"] = True + self.app.config["X_DOMAINS"] = "*" + + r, s = self._post() + self.assertEqual(STATUS_OK, r[STATUS]) + _id = r[self.id_field] + + with self.app.test_request_context(): + media_id = self.assertMediaStored(_id) + + methods = ["GET", "OPTIONS"] + for method in methods: + r = self.test_client.get( + "/media/%s" % media_id, + method=method, + headers=[("Origin", "http://example.com")], + ) + self.assert200(r.status_code) + self.assertEqual( + r.headers["Access-Control-Allow-Origin"], "http://example.com" + ) + self.assertEqual(r.headers["Vary"], "Origin") + self.assertTrue(method in r.headers["Access-Control-Allow-Methods"]) + def assertMediaField(self, _id, encoded, clean): # GET the file at the item endpoint r, s = self.parse_response(self.test_client.get("%s/%s" % (self.url, _id)))