Skip to content
This repository was archived by the owner on Feb 15, 2021. It is now read-only.

Commit 466d378

Browse files
committed
Add a signal that enables CORS headers.
If you have a use-case that requires running Python code to check if a site exists, we provide a Django signal that covers this. We have a ``check_request_enabled`` signal that provides the request. Here is an example configuration:: from corsheaders import signals from .models import Site def handler(sender, request, **kwargs): for site in Site.objects.all(): if request.host in site.domain: return True return False signals.check_request_enabled.connect(handler) If the signal returns ``True``, then the request will have headers added to it.
1 parent 997f371 commit 466d378

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

README.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ Note that ``CorsMiddleware`` needs to come before Django’s
6363
setting, otherwise the CORS headers will be lost from the 304
6464
not-modified responses, causing errors in some browsers.
6565

66+
Signals
67+
-------
68+
69+
If you have a use-case that requires running Python code to check if a site exists,
70+
we provide a Django signal that covers this.
71+
We have a ``check_request_enabled`` signal that provides the request.
72+
Here is an example configuration::
73+
74+
from corsheaders import signals
75+
from .models import Site
76+
77+
def handler(sender, request, **kwargs):
78+
for site in Site.objects.all():
79+
if request.host in site.domain:
80+
return True
81+
return False
82+
83+
signals.check_request_enabled.connect(handler)
84+
85+
If the signal returns ``True``,
86+
then the request will have headers added to it.
87+
6688
Configuration
6789
-------------
6890

corsheaders/middleware.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from django.apps.apps.get_model import get_model
1717

1818
from corsheaders import defaults as settings
19+
from corsheaders import signals
1920

2021

2122
ACCESS_CONTROL_ALLOW_ORIGIN = 'Access-Control-Allow-Origin'
@@ -118,7 +119,8 @@ def process_response(self, request, response):
118119

119120
if (not settings.CORS_ORIGIN_ALLOW_ALL and
120121
self.origin_not_found_in_white_lists(origin, url) and
121-
not self.regex_url_allow_all_match(request.path)):
122+
not self.regex_url_allow_all_match(request.path) and
123+
not self.check_signal(request)):
122124
return response
123125

124126
response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*" if (
@@ -154,7 +156,15 @@ def regex_domain_match(self, origin):
154156

155157
def is_enabled(self, request):
156158
return re.match(settings.CORS_URLS_REGEX, request.path) or \
157-
self.regex_url_allow_all_match(request.path)
159+
self.regex_url_allow_all_match(request.path) or \
160+
self.check_signal(request)
161+
162+
def check_signal(self, request):
163+
signal_response = signals.check_request_enabled.send(sender=None, request=request)
164+
for function, return_value in signal_response:
165+
if return_value:
166+
return True
167+
return False
158168

159169
def regex_url_allow_all_match(self, path):
160170
for url_pattern in settings.CORS_URLS_ALLOW_ALL_REGEX:

corsheaders/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33

44
class CorsModel(models.Model):
55
cors = models.CharField(max_length=255)
6+
7+
# For model registration
8+
from .signals import check_request_enabled

corsheaders/signals.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import django.dispatch
2+
3+
# Return Truthy values to enable a specific request.
4+
# This allows users to build custom logic into the request handling
5+
check_request_enabled = django.dispatch.Signal(
6+
providing_args=["request"]
7+
)

corsheaders/tests.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from corsheaders.middleware import ACCESS_CONTROL_ALLOW_METHODS
1010
from corsheaders.middleware import ACCESS_CONTROL_MAX_AGE
1111
from corsheaders import defaults as settings
12+
from corsheaders import signals
1213
from mock import Mock
1314
from mock import patch
1415

@@ -216,6 +217,19 @@ def test_process_response_not_in_whitelist(self, settings):
216217
processed = self.middleware.process_response(request, response)
217218
self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
218219

220+
def test_process_response_signal_works(self, settings):
221+
def handler(sender, request, **kwargs):
222+
return True
223+
settings.CORS_MODEL = None
224+
settings.CORS_ORIGIN_ALLOW_ALL = False
225+
settings.CORS_ORIGIN_WHITELIST = ['example.com']
226+
settings.CORS_URLS_REGEX = '^.*$'
227+
signals.check_request_enabled.connect(handler)
228+
response = HttpResponse()
229+
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
230+
processed = self.middleware.process_response(request, response)
231+
self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
232+
219233
def test_process_response_in_whitelist(self, settings):
220234
settings.CORS_MODEL = None
221235
settings.CORS_ORIGIN_ALLOW_ALL = False

0 commit comments

Comments
 (0)