diff --git a/flask_cors/core.py b/flask_cors/core.py index b37c9b3..c46f72d 100644 --- a/flask_cors/core.py +++ b/flask_cors/core.py @@ -13,7 +13,7 @@ from datetime import timedelta from six import string_types from flask import request, current_app -from werkzeug.datastructures import MultiDict +from werkzeug.datastructures import Headers, MultiDict LOG = logging.getLogger(__name__) @@ -226,6 +226,13 @@ def set_cors_headers(resp, options): LOG.debug('CORS have been already evaluated, skipping') return resp + # Some libraries, like OAuthlib, set resp.headers to non Multidict + # objects (Werkzeug Headers work as well). This is a problem because + # headers allow repeated values. + if (not isinstance(resp.headers, Headers) + and not isinstance(resp.headers, MultiDict)): + resp.headers = MultiDict(resp.headers) + headers_to_set = get_cors_headers(options, request.headers, request.method) LOG.debug('Settings CORS headers: %s', str(headers_to_set)) diff --git a/tests/core/test_override_headers.py b/tests/core/test_override_headers.py new file mode 100644 index 0000000..f76a1cd --- /dev/null +++ b/tests/core/test_override_headers.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" + test + ~~~~ + + Flask-Cors tests module +""" + +from ..base_test import FlaskCorsTestCase +from flask import Flask, Response + +from flask_cors import * +from flask_cors.core import * + +class ResponseHeadersOverrideTestCaseIntegration(FlaskCorsTestCase): + def setUp(self): + self.app = Flask(__name__) + CORS(self.app) + + @self.app.route('/') + def index(): + response = Response(headers={"custom": "dictionary"}) + return 'Welcome' + + def test_override_headers(self): + ''' + Ensure we work even if response.headers is set to something other than a MultiDict. + ''' + for resp in self.iter_responses('/'): + self.assertTrue(ACL_ORIGIN in resp.headers) + +if __name__ == "__main__": + unittest.main()