Skip to content

Commit

Permalink
Merge pull request #124 from corydolphin/multidict-headers
Browse files Browse the repository at this point in the history
Adds support for multiple headers of the same name. Fixes #122
  • Loading branch information
corydolphin committed May 8, 2015
2 parents 1fa5353 + 06c61df commit d6a198f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
18 changes: 8 additions & 10 deletions flask_cors/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from flask import _app_ctx_stack as stack
except ImportError:
from flask import _request_ctx_stack as stack

from werkzeug.datastructures import MultiDict

# Compatibility with old Pythons!
if not hasattr(logging, 'NullHandler'):
Expand Down Expand Up @@ -160,7 +160,7 @@ def get_allow_headers(options, acl_request_headers):

def get_cors_headers(options, request_headers, request_method, response_headers):
origin_to_set = get_cors_origin(options, request_headers.get('Origin'))
headers = {}
headers = MultiDict()

if origin_to_set is None: # CORS is not enabled for this route
return headers
Expand Down Expand Up @@ -198,10 +198,9 @@ def get_cors_headers(options, request_headers, request_method, response_headers)
# i.e. if we are not returning an asterisk, and there are multiple
# origins that can be matched.
if headers[ACL_ORIGIN] != '*' and len(options.get('origins')) > 1:
vary = ['Origin', response_headers.get('Vary')]
headers['Vary'] = ', '. join(v for v in vary if v is not None)
headers.add('Vary', 'Origin')

return dict((k, v) for k, v in headers.items() if v)
return MultiDict((k, v) for k, v in headers.items() if v)


def set_cors_headers(resp, options):
Expand All @@ -218,14 +217,13 @@ def set_cors_headers(resp, options):
debugLog('CORS have been already evaluated, skipping')
return resp

headers_to_set = get_cors_headers(options,
request.headers,
request.method,
resp.headers)
headers_to_set = get_cors_headers(options, request.headers, request.method,
resp.headers)

debugLog('Settings CORS headers: %s', str(headers_to_set))

for k, v in headers_to_set.items():
resp.headers[k] = v
resp.headers.add(k, v)

return resp

Expand Down
2 changes: 1 addition & 1 deletion flask_cors/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.0.0'
__version__ = '2.0.1'
33 changes: 33 additions & 0 deletions tests/decorator/test_duplicate_headers.py
Original file line number Diff line number Diff line change
@@ -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 AllowsMultipleHeaderEntries(FlaskCorsTestCase):
def setUp(self):
self.app = Flask(__name__)

@self.app.route('/test_multiple_set_cookie_headers')
@cross_origin()
def test_multiple_set_cookie_headers():
resp = Response("Foo bar baz")
resp.headers.add('set-cookie', 'foo')
resp.headers.add('set-cookie', 'bar')
return resp

def test_multiple_set_cookie_headers(self):
resp = self.get('/test_multiple_set_cookie_headers')
self.assertEqual(len(resp.headers.getlist('set-cookie')), 2)

if __name__ == "__main__":
unittest.main()
6 changes: 2 additions & 4 deletions tests/decorator/test_vary_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ def test_consistent_origin_concat(self):
'''

resp = self.get('/test_existing_vary_headers', origin="http://foo.com")
self.assertEqual(
resp.headers.get('Vary'),
'Origin, Accept-Encoding'
)
self.assertEqual(set(resp.headers.getlist('Vary')),
set(['Origin', 'Accept-Encoding']))


class AppConfigVaryHeaderTestCase(AppConfigTest,
Expand Down

0 comments on commit d6a198f

Please sign in to comment.