Skip to content

Commit

Permalink
Merge pull request #261 from circlingthesun/cors-header-fix
Browse files Browse the repository at this point in the history
Set cors headers when a response is returned or exception is raised
  • Loading branch information
almet committed Jan 31, 2015
2 parents 9588123 + a0ebd6e commit 37bee59
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
21 changes: 16 additions & 5 deletions cornice/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import functools
import warnings

from pyramid.response import Response

from cornice.validators import (
DEFAULT_VALIDATORS,
DEFAULT_FILTERS,
Expand Down Expand Up @@ -519,11 +521,16 @@ def wrapper(request):

# only call the view if we don't have validation errors
if len(request.errors) == 0:
# if we have an object, the request had already been passed to it
if ob:
response = view_()
else:
response = view_(request)
try:
# if we have an object, the request had already been passed to it
if ob:
response = view_()
else:
response = view_(request)
except:
# cors headers need to be set if an exception was raised
request.info['cors_checked'] = False
raise

# check for errors and return them if any
if len(request.errors) > 0:
Expand All @@ -532,6 +539,10 @@ def wrapper(request):
request.info['cors_checked'] = False
return args['error_handler'](request.errors)

# if the view returns its own response, cors headers need to be set
if isinstance(response, Response):
request.info['cors_checked'] = False

# We can't apply filters at this level, since "response" may not have
# been rendered into a proper Response object yet. Instead, give the
# request a reference to its api_kwargs so that a tween can apply them.
Expand Down
20 changes: 19 additions & 1 deletion cornice/tests/test_cors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
from pyramid import testing
from pyramid.exceptions import NotFound
from pyramid.exceptions import NotFound, HTTPBadRequest
from pyramid.response import Response

from webtest import TestApp
Expand Down Expand Up @@ -75,6 +75,14 @@ def get_some_bacon(request):
raise NotFound(detail='Not. Found.')
return "yay"

@bacon.post()
def post_some_bacon(request):
return Response()

@bacon.put()
def put_some_bacon(request):
raise HTTPBadRequest()

from pyramid.view import view_config


Expand Down Expand Up @@ -289,6 +297,16 @@ def test_404_returns_CORS_headers(self):
headers={'Origin': 'notmyidea.org'})
self.assertIn('Access-Control-Allow-Origin', resp.headers)

def test_response_returns_CORS_headers(self):
resp = self.app.post('/bacon/response', status=200,
headers={'Origin': 'notmyidea.org'})
self.assertIn('Access-Control-Allow-Origin', resp.headers)

def test_raise_returns_CORS_headers(self):
resp = self.app.put('/bacon/raise', status=400,
headers={'Origin': 'notmyidea.org'})
self.assertIn('Access-Control-Allow-Origin', resp.headers)

def test_existing_non_service_route(self):
resp = self.app.get('/noservice', status=200,
headers={'Origin': 'notmyidea.org'})
Expand Down

0 comments on commit 37bee59

Please sign in to comment.