Repository: zestedesavoir/django-cors-middleware
Branch: master
Commit: 50d07ca143ea
Files: 20
Total size: 35.9 KB
Directory structure:
gitextract_o3_czq0e/
├── .coveragerc
├── .github/
│ └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── MANIFEST.in
├── README.rst
├── corsheaders/
│ ├── __init__.py
│ ├── defaults.py
│ ├── middleware.py
│ ├── migrations/
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── signals.py
│ └── tests.py
├── flake8.cfg
├── setup.cfg
├── setup.py
├── tests.py
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .coveragerc
================================================
[run]
source=corsheaders
[report]
omit=*tests*,*__init__*
show_missing=True
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain about missing debug-only code:
def __repr__
if self\.debug
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
**Issue(s)** :
================================================
FILE: .gitignore
================================================
*.pyc
*.egg-info
build/
dist/
.eggs/
.idea/
.tox/
# Packages
*.egg
*.egg-info
.coverage
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
================================================
FILE: .travis.yml
================================================
language: python
python:
- 2.7
- 3.4
- 3.5
- 3.6
sudo: false
install:
- pip install tox-travis
script:
- tox
# Coverage data generation
- pip install "Django<2.2" flake8 coverage codecov
- flake8 --config flake8.cfg .
- coverage run setup.py test
- coverage report
after_success:
- codecov
================================================
FILE: LICENSE.txt
================================================
Original work Copyright 2013 Otto Yiu and other contributors
Modified work Copyright 2016 Zeste de Savoir
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: MANIFEST.in
================================================
include README.rst
include LICENSE.txt
================================================
FILE: README.rst
================================================
django-cors-middleware
======================
``django-cors-middleware`` is **depreciated**, please use `adamchainz/django-cors-headers <https://github.com/adamchainz/django-cors-headers>`_ instead.
It was created at a time when ``django-cors-headers`` was not maintained, but it is well maintained now and there is no need to have two different packages for that.
Extract from `adamchainz/django-cors-headers README's About section <https://github.com/adamchainz/django-cors-headers>`_:
**django-cors-headers** was created in January 2013 by Otto Yiu. It went
unmaintained from August 2015 and was forked in January 2016 to the package
`django-cors-middleware <https://github.com/zestedesavoir/django-cors-middleware>`_
by Laville Augustin at Zeste de Savoir.
In September 2016, Adam Johnson, Ed Morley, and others gained maintenance
responsibility for **django-cors-headers**
(`Issue 110 <https://github.com/adamchainz/django-cors-headers/issues/110>`__)
from Otto Yiu.
Basically all of the changes in the forked **django-cors-middleware** were
merged back, or re-implemented in a different way, so it should be possible to
switch back. If there's a feature that hasn't been merged, please open an issue
about it.
================================================
FILE: corsheaders/__init__.py
================================================
__version__ = '999'
================================================
FILE: corsheaders/defaults.py
================================================
from django.conf import settings
default_headers = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken',
'user-agent',
'accept-encoding',
'cache-control',
)
CORS_ALLOW_HEADERS = getattr(settings, 'CORS_ALLOW_HEADERS', default_headers)
default_methods = (
'GET',
'POST',
'PUT',
'PATCH',
'DELETE',
'OPTIONS',
)
CORS_ALLOW_METHODS = getattr(settings, 'CORS_ALLOW_METHODS', default_methods)
CORS_ALLOW_CREDENTIALS = getattr(settings, 'CORS_ALLOW_CREDENTIALS', False)
CORS_PREFLIGHT_MAX_AGE = getattr(settings, 'CORS_PREFLIGHT_MAX_AGE', 86400)
CORS_ORIGIN_ALLOW_ALL = getattr(settings, 'CORS_ORIGIN_ALLOW_ALL', False)
CORS_ORIGIN_WHITELIST = getattr(settings, 'CORS_ORIGIN_WHITELIST', ())
CORS_ORIGIN_REGEX_WHITELIST = getattr(
settings,
'CORS_ORIGIN_REGEX_WHITELIST',
())
CORS_EXPOSE_HEADERS = getattr(settings, 'CORS_EXPOSE_HEADERS', ())
CORS_URLS_REGEX = getattr(settings, 'CORS_URLS_REGEX', '^.*$')
CORS_MODEL = getattr(settings, 'CORS_MODEL', None)
CORS_REPLACE_HTTPS_REFERER = getattr(
settings,
'CORS_REPLACE_HTTPS_REFERER',
False)
CORS_URLS_ALLOW_ALL_REGEX = getattr(settings, 'CORS_URLS_ALLOW_ALL_REGEX', ())
================================================
FILE: corsheaders/middleware.py
================================================
import re
from django import http
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
from django.apps import apps
from django.utils.cache import patch_vary_headers
from django.utils.deprecation import MiddlewareMixin
from corsheaders import defaults as settings
from corsheaders import signals
get_model = apps.get_model
ACCESS_CONTROL_ALLOW_ORIGIN = 'Access-Control-Allow-Origin'
ACCESS_CONTROL_EXPOSE_HEADERS = 'Access-Control-Expose-Headers'
ACCESS_CONTROL_ALLOW_CREDENTIALS = 'Access-Control-Allow-Credentials'
ACCESS_CONTROL_ALLOW_HEADERS = 'Access-Control-Allow-Headers'
ACCESS_CONTROL_ALLOW_METHODS = 'Access-Control-Allow-Methods'
ACCESS_CONTROL_MAX_AGE = 'Access-Control-Max-Age'
class CorsPostCsrfMiddleware(MiddlewareMixin):
def _https_referer_replace_reverse(self, request):
"""
Put the HTTP_REFERER back to its original value and delete the
temporary storage
"""
if (settings.CORS_REPLACE_HTTPS_REFERER and
'ORIGINAL_HTTP_REFERER' in request.META):
http_referer = request.META['ORIGINAL_HTTP_REFERER']
request.META['HTTP_REFERER'] = http_referer
del request.META['ORIGINAL_HTTP_REFERER']
def process_request(self, request):
self._https_referer_replace_reverse(request)
return None
def process_view(self, request, callback, callback_args, callback_kwargs):
self._https_referer_replace_reverse(request)
return None
class CorsMiddleware(MiddlewareMixin):
def _https_referer_replace(self, request):
"""
When https is enabled, django CSRF checking includes referer checking
which breaks when using CORS. This function updates the HTTP_REFERER
header to make sure it matches HTTP_HOST, provided that our cors logic
succeeds
"""
origin = request.META.get('HTTP_ORIGIN')
if (request.is_secure() and origin and
'ORIGINAL_HTTP_REFERER' not in request.META):
url = urlparse(origin)
if (not settings.CORS_ORIGIN_ALLOW_ALL and
self.origin_not_found_in_white_lists(origin, url)):
return
try:
http_referer = request.META['HTTP_REFERER']
http_host = "https://%s/" % request.META['HTTP_HOST']
request.META = request.META.copy()
request.META['ORIGINAL_HTTP_REFERER'] = http_referer
request.META['HTTP_REFERER'] = http_host
except KeyError:
pass
def process_request(self, request):
"""
If CORS preflight header, then create an
empty body response (200 OK) and return it
Django won't bother calling any other request
view/exception middleware along with the requested view;
it will call any response middlewares
"""
if self.is_enabled(request) and settings.CORS_REPLACE_HTTPS_REFERER:
self._https_referer_replace(request)
if (self.is_enabled(request) and
request.method == 'OPTIONS' and
"HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
response = http.HttpResponse()
return response
return None
def process_view(self, request, callback, callback_args, callback_kwargs):
"""
Do the referer replacement here as well
"""
if self.is_enabled(request) and settings.CORS_REPLACE_HTTPS_REFERER:
self._https_referer_replace(request)
return None
def process_response(self, request, response):
"""
Add the respective CORS headers
"""
origin = request.META.get('HTTP_ORIGIN')
if self.is_enabled(request) and origin:
# todo: check hostname from db instead
url = urlparse(origin)
if settings.CORS_MODEL is not None:
model = get_model(*settings.CORS_MODEL.split('.'))
if model.objects.filter(cors=url.netloc).exists():
response[ACCESS_CONTROL_ALLOW_ORIGIN] = origin
if (not settings.CORS_ORIGIN_ALLOW_ALL and
self.origin_not_found_in_white_lists(origin, url) and
not self.regex_url_allow_all_match(request.path) and
not self.check_signal(request)):
return response
if settings.CORS_ORIGIN_ALLOW_ALL and not settings.CORS_ALLOW_CREDENTIALS:
response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*"
else:
response[ACCESS_CONTROL_ALLOW_ORIGIN] = origin
patch_vary_headers(response, ['Origin'])
if len(settings.CORS_EXPOSE_HEADERS):
response[ACCESS_CONTROL_EXPOSE_HEADERS] = ', '.join(
settings.CORS_EXPOSE_HEADERS)
if settings.CORS_ALLOW_CREDENTIALS:
response[ACCESS_CONTROL_ALLOW_CREDENTIALS] = 'true'
if request.method == 'OPTIONS':
response[ACCESS_CONTROL_ALLOW_HEADERS] = ', '.join(
settings.CORS_ALLOW_HEADERS)
response[ACCESS_CONTROL_ALLOW_METHODS] = ', '.join(
settings.CORS_ALLOW_METHODS)
if settings.CORS_PREFLIGHT_MAX_AGE:
response[ACCESS_CONTROL_MAX_AGE] = \
settings.CORS_PREFLIGHT_MAX_AGE
return response
def origin_not_found_in_white_lists(self, origin, url):
return (url.netloc not in settings.CORS_ORIGIN_WHITELIST and
not self.regex_domain_match(origin))
def regex_domain_match(self, origin):
for domain_pattern in settings.CORS_ORIGIN_REGEX_WHITELIST:
if re.match(domain_pattern, origin):
return origin
def is_enabled(self, request):
return re.match(settings.CORS_URLS_REGEX, request.path) or \
self.regex_url_allow_all_match(request.path) or \
self.check_signal(request)
def check_signal(self, request):
signal_response = signals.check_request_enabled.send(
sender=None, request=request
)
for function, return_value in signal_response:
if return_value:
return True
return False
def regex_url_allow_all_match(self, path):
for url_pattern in settings.CORS_URLS_ALLOW_ALL_REGEX:
if re.match(url_pattern, path):
return path
================================================
FILE: corsheaders/migrations/0001_initial.py
================================================
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2017-01-18 21:36
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='CorsModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cors', models.CharField(max_length=255)),
],
),
]
================================================
FILE: corsheaders/migrations/__init__.py
================================================
================================================
FILE: corsheaders/models.py
================================================
from django.db import models
# For signal registration
from .signals import check_request_enabled # noqa
class CorsModel(models.Model):
cors = models.CharField(max_length=255)
================================================
FILE: corsheaders/signals.py
================================================
import django.dispatch
# Return Truthy values to enable a specific request.
# This allows users to build custom logic into the request handling
check_request_enabled = django.dispatch.Signal(
providing_args=["request"]
)
================================================
FILE: corsheaders/tests.py
================================================
from django.conf.urls import url
from django.http import HttpResponse
from django.test import TestCase
from corsheaders.middleware import CorsMiddleware, CorsPostCsrfMiddleware
from corsheaders.middleware import ACCESS_CONTROL_ALLOW_ORIGIN
from corsheaders.middleware import ACCESS_CONTROL_EXPOSE_HEADERS
from corsheaders.middleware import ACCESS_CONTROL_ALLOW_CREDENTIALS
from corsheaders.middleware import ACCESS_CONTROL_ALLOW_HEADERS
from corsheaders.middleware import ACCESS_CONTROL_ALLOW_METHODS
from corsheaders.middleware import ACCESS_CONTROL_MAX_AGE
from corsheaders import defaults as settings
from corsheaders import signals
from mock import Mock
from mock import patch
def test_view(request):
return HttpResponse("Test view")
def test_view_http401(request):
return HttpResponse('Unauthorized', status=401)
urlpatterns = [
url(r'^test-view/$', test_view, name='test-view'),
url(r'^test-view-http401/$', test_view_http401, name='test-view-http401'),
]
class settings_override(object):
def __init__(self, **kwargs):
self.overrides = kwargs
def __enter__(self):
self.old = dict((key, getattr(settings, key)) for key in self.overrides)
settings.__dict__.update(self.overrides)
def __exit__(self, exc, value, tb):
settings.__dict__.update(self.old)
class TestCorsMiddlewareProcessRequest(TestCase):
def setUp(self):
self.middleware = CorsMiddleware()
def test_process_request(self):
request = Mock(path='/')
request.method = 'OPTIONS'
request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
with settings_override(CORS_URLS_REGEX='^.*$'):
response = self.middleware.process_request(request)
self.assertIsInstance(response, HttpResponse)
def test_process_request_empty_header(self):
request = Mock(path='/')
request.method = 'OPTIONS'
request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': ''}
with settings_override(CORS_URLS_REGEX='^.*$'):
response = self.middleware.process_request(request)
self.assertIsInstance(response, HttpResponse)
def test_process_request_no_header(self):
request = Mock(path='/')
request.method = 'OPTIONS'
request.META = {}
response = self.middleware.process_request(request)
self.assertIsNone(response)
def test_process_request_not_options(self):
request = Mock(path='/')
request.method = 'GET'
request.META = {'HTTP_ACCESS_CONTROL_REQUEST_METHOD': 'value'}
response = self.middleware.process_request(request)
self.assertIsNone(response)
def test_process_request_replace_https_referer(self):
post_middleware = CorsPostCsrfMiddleware()
request = Mock(path='/')
request.method = 'GET'
request.is_secure = lambda: True
# make sure it doesnt blow up when HTTP_REFERER is not present
request.META = {
'HTTP_HOST': 'foobar.com',
'HTTP_ORIGIN': 'https://foo.google.com',
}
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_request(request)
self.assertIsNone(response)
# make sure it doesnt blow up when HTTP_HOST is not present
request.META = {
'HTTP_REFERER': 'http://foo.google.com/',
'HTTP_ORIGIN': 'https://foo.google.com',
}
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_request(request)
self.assertIsNone(response)
request.is_secure = lambda: False
request.META = {
'HTTP_REFERER': 'http://foo.google.com/',
'HTTP_HOST': 'foobar.com',
'HTTP_ORIGIN': 'http://foo.google.com',
}
# test that we won't replace if the request is not secure
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_request(request)
self.assertIsNone(response)
self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
self.assertEquals(request.META['HTTP_REFERER'], 'http://foo.google.com/')
request.is_secure = lambda: True
request.META = {
'HTTP_REFERER': 'https://foo.google.com/',
'HTTP_HOST': 'foobar.com',
'HTTP_ORIGIN': 'https://foo.google.com',
}
# test that we won't replace with the setting off
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*'):
response = self.middleware.process_request(request)
self.assertIsNone(response)
self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_request(request)
self.assertIsNone(response)
self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')
# make sure the replace code is idempotent
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_view(request, None, None, None)
self.assertIsNone(response)
self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')
with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
post_middleware.process_request(request)
self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')
with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
response = post_middleware.process_request(request)
self.assertIsNone(response)
def test_process_view_replace_https_referer(self):
post_middleware = CorsPostCsrfMiddleware()
request = Mock(path='/')
request.method = 'GET'
request.is_secure = lambda: True
request.META = {
'HTTP_REFERER': 'https://foo.google.com/',
'HTTP_HOST': 'foobar.com',
'HTTP_ORIGIN': 'https://foo.google.com',
}
with settings_override(CORS_URLS_REGEX='^.*$',
CORS_ORIGIN_REGEX_WHITELIST='.*google.*',
CORS_REPLACE_HTTPS_REFERER=True):
response = self.middleware.process_view(request, None, None, None)
self.assertIsNone(response)
self.assertEquals(request.META['ORIGINAL_HTTP_REFERER'], 'https://foo.google.com/')
self.assertEquals(request.META['HTTP_REFERER'], 'https://foobar.com/')
with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
post_middleware.process_view(request, None, None, None)
self.assertTrue('ORIGINAL_HTTP_REFERER' not in request.META)
self.assertEquals(request.META['HTTP_REFERER'], 'https://foo.google.com/')
with settings_override(CORS_URLS_REGEX='^.*$', CORS_REPLACE_HTTPS_REFERER=True):
response = post_middleware.process_view(request, None, None, None)
self.assertIsNone(response)
@patch('corsheaders.middleware.settings')
class TestCorsMiddlewareProcessResponse(TestCase):
def setUp(self):
self.middleware = CorsMiddleware()
def assertAccessControlAllowOriginEquals(self, response, header):
self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, response, "Response %r does "
"NOT have %r header" % (response, ACCESS_CONTROL_ALLOW_ORIGIN))
self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], header)
def test_process_response_no_origin(self, settings):
settings.CORS_MODEL = None
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={})
processed = self.middleware.process_response(request, response)
self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
def test_process_response_not_in_whitelist(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ORIGIN_WHITELIST = ['example.com']
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
processed = self.middleware.process_response(request, response)
self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
def test_process_response_signal_works(self, settings):
def handler(sender, request, **kwargs):
return True
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ORIGIN_WHITELIST = ['example.com']
settings.CORS_URLS_REGEX = '^.*$'
signals.check_request_enabled.connect(handler)
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
processed = self.middleware.process_response(request, response)
self.assertIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
def test_process_response_in_whitelist(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foobar.it'})
processed = self.middleware.process_response(request, response)
self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')
def test_process_response_expose_headers(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_EXPOSE_HEADERS = ['accept', 'origin', 'content-type']
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
processed = self.middleware.process_response(request, response)
self.assertEqual(processed[ACCESS_CONTROL_EXPOSE_HEADERS],
'accept, origin, content-type')
def test_process_response_dont_expose_headers(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_EXPOSE_HEADERS = []
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
processed = self.middleware.process_response(request, response)
self.assertNotIn(ACCESS_CONTROL_EXPOSE_HEADERS, processed)
def test_process_response_allow_credentials(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_ALLOW_CREDENTIALS = True
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
processed = self.middleware.process_response(request, response)
self.assertEqual(processed[ACCESS_CONTROL_ALLOW_CREDENTIALS], 'true')
def test_process_response_dont_allow_credentials(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_ALLOW_CREDENTIALS = False
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://example.com'})
processed = self.middleware.process_response(request, response)
self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, processed)
def test_process_response_options_method(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
settings.CORS_PREFLIGHT_MAX_AGE = 1002
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request_headers = {'HTTP_ORIGIN': 'http://example.com'}
request = Mock(path='/', META=request_headers, method='OPTIONS')
processed = self.middleware.process_response(request, response)
self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
'content-type, origin')
self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
self.assertEqual(processed[ACCESS_CONTROL_MAX_AGE], '1002')
def test_process_response_options_method_no_max_age(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_ALLOW_HEADERS = ['content-type', 'origin']
settings.CORS_ALLOW_METHODS = ['GET', 'OPTIONS']
settings.CORS_PREFLIGHT_MAX_AGE = 0
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request_headers = {'HTTP_ORIGIN': 'http://example.com'}
request = Mock(path='/', META=request_headers, method='OPTIONS')
processed = self.middleware.process_response(request, response)
self.assertEqual(processed[ACCESS_CONTROL_ALLOW_HEADERS],
'content-type, origin')
self.assertEqual(processed[ACCESS_CONTROL_ALLOW_METHODS], 'GET, OPTIONS')
self.assertNotIn(ACCESS_CONTROL_MAX_AGE, processed)
def test_process_response_whitelist_with_port(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ALLOW_METHODS = ['OPTIONS']
settings.CORS_ORIGIN_WHITELIST = ('localhost:9000',)
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request_headers = {'HTTP_ORIGIN': 'http://localhost:9000'}
request = Mock(path='/', META=request_headers, method='OPTIONS')
processed = self.middleware.process_response(request, response)
self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_CREDENTIALS, None), 'true')
def test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?google\.com$', )
settings.CORS_ALLOW_CREDENTIALS = True
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ALLOW_METHODS = ['OPTIONS']
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
request = Mock(path='/', META=request_headers, method='OPTIONS')
processed = self.middleware.process_response(request, response)
self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')
def test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_REGEX_WHITELIST = ('^http?://(\w+\.)?yahoo\.com$', )
settings.CORS_ALLOW_CREDENTIALS = True
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ALLOW_METHODS = ['OPTIONS']
settings.CORS_URLS_REGEX = '^.*$'
response = HttpResponse()
request_headers = {'HTTP_ORIGIN': 'http://foo.google.com'}
request = Mock(path='/', META=request_headers, method='OPTIONS')
processed = self.middleware.process_response(request, response)
self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), None)
def test_process_response_when_custom_model_enabled(self, settings):
from corsheaders.models import CorsModel
CorsModel.objects.create(cors='foo.google.com')
settings.CORS_ORIGIN_REGEX_WHITELIST = ()
settings.CORS_ALLOW_CREDENTIALS = False
settings.CORS_ORIGIN_ALLOW_ALL = False
settings.CORS_ALLOW_METHODS = settings.default_methods
settings.CORS_URLS_REGEX = '^.*$'
settings.CORS_MODEL = 'corsheaders.CorsModel'
response = HttpResponse()
request = Mock(path='/', META={'HTTP_ORIGIN': 'http://foo.google.com'})
processed = self.middleware.process_response(request, response)
self.assertEqual(processed.get(ACCESS_CONTROL_ALLOW_ORIGIN, None), 'http://foo.google.com')
def test_process_response_in_allow_all_path(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
# settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
settings.CORS_URLS_REGEX = '^.*$'
settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$',)
response = HttpResponse()
request = Mock(path='/api/data', META={'HTTP_ORIGIN': 'http://foobar.it'})
processed = self.middleware.process_response(request, response)
self.assertAccessControlAllowOriginEquals(processed, 'http://foobar.it')
def test_process_response_not_in_allow_all_path(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = False
# settings.CORS_ORIGIN_WHITELIST = ['example.com', 'foobar.it']
settings.CORS_URLS_REGEX = '^.*$'
settings.CORS_URLS_ALLOW_ALL_REGEX = (r'^/api/.*$',)
response = HttpResponse()
request = Mock(path='/data', META={'HTTP_ORIGIN': 'http://foobar.it'})
processed = self.middleware.process_response(request, response)
self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, processed)
def test_middleware_integration_get(self, settings):
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_URLS_REGEX = '^.*$'
response = self.client.get('/test-view/', HTTP_ORIGIN='http://foobar.it')
self.assertEqual(response.status_code, 200)
self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')
def test_middleware_integration_options(self, settings):
settings.CORS_MODEL = None
settings.CORS_URLS_REGEX = '^.*$'
settings.CORS_ALLOW_CREDENTIALS = True
settings.CORS_ORIGIN_ALLOW_ALL = True
response = self.client.options(
'/test-view/',
HTTP_ORIGIN='http://foobar.it',
HTTP_ACCESS_CONTROL_REQUEST_METHOD='value',
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response[ACCESS_CONTROL_ALLOW_ORIGIN], 'http://foobar.it')
self.assertEqual(response['Vary'], 'Origin')
def test_middleware_integration_get_auth_view(self, settings):
"""
It's not clear whether the header should still be set for non-HTTP200
when not a preflight request. However this is the existing behaviour for
django-cors-middleware, so at least this test makes that explicit, especially
since for the switch to Django 1.10, special-handling will need to be put in
place to preserve this behaviour. See `ExceptionMiddleware` mention here:
https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
"""
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_URLS_REGEX = '^.*$'
response = self.client.get('/test-view-http401/', HTTP_ORIGIN='http://foobar.it')
self.assertEqual(response.status_code, 401)
self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')
def test_middleware_integration_preflight_auth_view(self, settings):
"""
Ensure HTTP200 and header still set, for preflight requests to views requiring
authentication. See: https://github.com/ottoyiu/django-cors-headers/issues/3
"""
settings.CORS_MODEL = None
settings.CORS_ORIGIN_ALLOW_ALL = True
settings.CORS_URLS_REGEX = '^.*$'
response = self.client.options('/test-view-http401/',
HTTP_ORIGIN='http://foobar.it',
HTTP_ACCESS_CONTROL_REQUEST_METHOD='value')
self.assertEqual(response.status_code, 200)
self.assertAccessControlAllowOriginEquals(response, 'http://foobar.it')
================================================
FILE: flake8.cfg
================================================
[flake8]
max-complexity=12
exclude=tests.py,.tox,*.egg
max-line-length=120
================================================
FILE: setup.cfg
================================================
[metadata]
description-file = README.rst
================================================
FILE: setup.py
================================================
#!/usr/bin/env python
from corsheaders import __version__
from setuptools import setup, find_packages
setup(
name='django-cors-middleware',
version=__version__,
description='django-cors-middleware is a Django application for handling the server headers required for Cross-Orig'
'in Resource Sharing (CORS). Fork of django-cors-headers.',
author='Zeste de Savoir',
author_email='dev@gustavi.net',
url='https://github.com/zestedesavoir/django-cors-middleware',
packages=find_packages(),
license='MIT License',
keywords='django cors middleware rest api',
platforms=['any'],
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Topic :: Software Development :: Libraries :: Application Frameworks',
'Topic :: Software Development :: Libraries :: Python Modules',
],
install_requires=[],
tests_require=['mock >= 1.0'],
test_suite='tests.main',
)
================================================
FILE: tests.py
================================================
#!/usr/bin/env python
"""
"""
import sys
def run_tests():
import django
from django.conf import global_settings
from django.conf import settings
if django.VERSION >= (1, 10):
middleware_setting = 'MIDDLEWARE'
else:
middleware_setting = 'MIDDLEWARE_CLASSES'
middleware = list(getattr(global_settings, middleware_setting) or [])
middleware.append('corsheaders.middleware.CorsMiddleware')
config = {
'INSTALLED_APPS': [
'corsheaders',
],
'DATABASES': {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'TEST_NAME': ':memory:',
},
},
'ROOT_URLCONF': 'corsheaders.tests',
middleware_setting: middleware,
}
settings.configure(**config)
if hasattr(django, 'setup'):
django.setup()
try:
from django.test.runner import DiscoverRunner as Runner
except ImportError:
from django.test.simple import DjangoTestSuiteRunner as Runner
test_runner = Runner(verbosity=1)
return test_runner.run_tests(['corsheaders'])
def main():
failures = run_tests()
sys.exit(failures)
if __name__ == '__main__':
main()
================================================
FILE: tox.ini
================================================
[tox]
downloadcache = {toxworkdir}/cache/
envlist =
py{27,34,35,36,37}-django110
py{27,34,35,36,37}-django111
# First Django version that drops Python 2 support
py{34,35,36,37}-django20
# First Django version that drops support for Python versions below 3.5
py{35,36,37}-django21
[testenv]
commands = python setup.py test
deps =
django18: Django >=1.8, <1.9
django19: Django >=1.9, <2.0
django110: Django >=1.10, <1.11
django111: Django >=1.11, <2.0
django20: Django >=2.0, <2.1
django21: Django >=2.1, <2.2
gitextract_o3_czq0e/ ├── .coveragerc ├── .github/ │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── corsheaders/ │ ├── __init__.py │ ├── defaults.py │ ├── middleware.py │ ├── migrations/ │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── signals.py │ └── tests.py ├── flake8.cfg ├── setup.cfg ├── setup.py ├── tests.py └── tox.ini
SYMBOL INDEX (55 symbols across 5 files)
FILE: corsheaders/middleware.py
class CorsPostCsrfMiddleware (line 26) | class CorsPostCsrfMiddleware(MiddlewareMixin):
method _https_referer_replace_reverse (line 28) | def _https_referer_replace_reverse(self, request):
method process_request (line 39) | def process_request(self, request):
method process_view (line 43) | def process_view(self, request, callback, callback_args, callback_kwar...
class CorsMiddleware (line 48) | class CorsMiddleware(MiddlewareMixin):
method _https_referer_replace (line 50) | def _https_referer_replace(self, request):
method process_request (line 75) | def process_request(self, request):
method process_view (line 94) | def process_view(self, request, callback, callback_args, callback_kwar...
method process_response (line 102) | def process_response(self, request, response):
method origin_not_found_in_white_lists (line 146) | def origin_not_found_in_white_lists(self, origin, url):
method regex_domain_match (line 150) | def regex_domain_match(self, origin):
method is_enabled (line 155) | def is_enabled(self, request):
method check_signal (line 160) | def check_signal(self, request):
method regex_url_allow_all_match (line 169) | def regex_url_allow_all_match(self, path):
FILE: corsheaders/migrations/0001_initial.py
class Migration (line 8) | class Migration(migrations.Migration):
FILE: corsheaders/models.py
class CorsModel (line 7) | class CorsModel(models.Model):
FILE: corsheaders/tests.py
function test_view (line 17) | def test_view(request):
function test_view_http401 (line 21) | def test_view_http401(request):
class settings_override (line 31) | class settings_override(object):
method __init__ (line 32) | def __init__(self, **kwargs):
method __enter__ (line 35) | def __enter__(self):
method __exit__ (line 39) | def __exit__(self, exc, value, tb):
class TestCorsMiddlewareProcessRequest (line 43) | class TestCorsMiddlewareProcessRequest(TestCase):
method setUp (line 45) | def setUp(self):
method test_process_request (line 48) | def test_process_request(self):
method test_process_request_empty_header (line 56) | def test_process_request_empty_header(self):
method test_process_request_no_header (line 64) | def test_process_request_no_header(self):
method test_process_request_not_options (line 71) | def test_process_request_not_options(self):
method test_process_request_replace_https_referer (line 78) | def test_process_request_replace_https_referer(self):
method test_process_view_replace_https_referer (line 163) | def test_process_view_replace_https_referer(self):
class TestCorsMiddlewareProcessResponse (line 192) | class TestCorsMiddlewareProcessResponse(TestCase):
method setUp (line 194) | def setUp(self):
method assertAccessControlAllowOriginEquals (line 197) | def assertAccessControlAllowOriginEquals(self, response, header):
method test_process_response_no_origin (line 202) | def test_process_response_no_origin(self, settings):
method test_process_response_not_in_whitelist (line 210) | def test_process_response_not_in_whitelist(self, settings):
method test_process_response_signal_works (line 220) | def test_process_response_signal_works(self, settings):
method test_process_response_in_whitelist (line 233) | def test_process_response_in_whitelist(self, settings):
method test_process_response_expose_headers (line 243) | def test_process_response_expose_headers(self, settings):
method test_process_response_dont_expose_headers (line 254) | def test_process_response_dont_expose_headers(self, settings):
method test_process_response_allow_credentials (line 264) | def test_process_response_allow_credentials(self, settings):
method test_process_response_dont_allow_credentials (line 274) | def test_process_response_dont_allow_credentials(self, settings):
method test_process_response_options_method (line 284) | def test_process_response_options_method(self, settings):
method test_process_response_options_method_no_max_age (line 300) | def test_process_response_options_method_no_max_age(self, settings):
method test_process_response_whitelist_with_port (line 316) | def test_process_response_whitelist_with_port(self, settings):
method test_process_response_adds_origin_when_domain_found_in_origin_regex_whitelist (line 328) | def test_process_response_adds_origin_when_domain_found_in_origin_rege...
method test_process_response_will_not_add_origin_when_domain_not_found_in_origin_regex_whitelist (line 341) | def test_process_response_will_not_add_origin_when_domain_not_found_in...
method test_process_response_when_custom_model_enabled (line 354) | def test_process_response_when_custom_model_enabled(self, settings):
method test_process_response_in_allow_all_path (line 368) | def test_process_response_in_allow_all_path(self, settings):
method test_process_response_not_in_allow_all_path (line 379) | def test_process_response_not_in_allow_all_path(self, settings):
method test_middleware_integration_get (line 390) | def test_middleware_integration_get(self, settings):
method test_middleware_integration_options (line 398) | def test_middleware_integration_options(self, settings):
method test_middleware_integration_get_auth_view (line 412) | def test_middleware_integration_get_auth_view(self, settings):
method test_middleware_integration_preflight_auth_view (line 428) | def test_middleware_integration_preflight_auth_view(self, settings):
FILE: tests.py
function run_tests (line 7) | def run_tests():
function main (line 47) | def main():
Condensed preview — 20 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (39K chars).
[
{
"path": ".coveragerc",
"chars": 465,
"preview": "[run]\nsource=corsheaders\n\n[report]\nomit=*tests*,*__init__*\nshow_missing=True\n\nexclude_lines =\n # Have to re-enable th"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 15,
"preview": "**Issue(s)** : "
},
{
"path": ".gitignore",
"chars": 165,
"preview": "*.pyc\n*.egg-info\nbuild/ \ndist/\n.eggs/\n.idea/\n.tox/\n\n# Packages\n*.egg\n*.egg-info\n.coverage\ndist\nbuild\neggs\nparts\nbin\nvar\n"
},
{
"path": ".travis.yml",
"chars": 295,
"preview": "language: python\npython:\n- 2.7\n- 3.4\n- 3.5\n- 3.6\n\n\nsudo: false\n\ninstall:\n- pip install tox-travis\n\nscript:\n- tox\n\n# Cove"
},
{
"path": "LICENSE.txt",
"chars": 1129,
"preview": "Original work Copyright 2013 Otto Yiu and other contributors\rModified work Copyright 2016 Zeste de Savoir\r\rPermission is"
},
{
"path": "MANIFEST.in",
"chars": 39,
"preview": "include README.rst\ninclude LICENSE.txt\n"
},
{
"path": "README.rst",
"chars": 1289,
"preview": "django-cors-middleware\r\n======================\r\n\r\n``django-cors-middleware`` is **depreciated**, please use `adamchainz/"
},
{
"path": "corsheaders/__init__.py",
"chars": 20,
"preview": "__version__ = '999'\n"
},
{
"path": "corsheaders/defaults.py",
"chars": 1245,
"preview": "from django.conf import settings\n\ndefault_headers = (\n 'x-requested-with',\n 'content-type',\n 'accept',\n 'ori"
},
{
"path": "corsheaders/middleware.py",
"chars": 6533,
"preview": "import re\n\nfrom django import http\ntry:\n from urlparse import urlparse\nexcept ImportError:\n from urllib.parse impo"
},
{
"path": "corsheaders/migrations/0001_initial.py",
"chars": 554,
"preview": "# -*- coding: utf-8 -*-\n# Generated by Django 1.10.1 on 2017-01-18 21:36\nfrom __future__ import unicode_literals\n\nfrom d"
},
{
"path": "corsheaders/migrations/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "corsheaders/models.py",
"chars": 184,
"preview": "from django.db import models\n\n# For signal registration\nfrom .signals import check_request_enabled # noqa\n\n\nclass CorsM"
},
{
"path": "corsheaders/signals.py",
"chars": 226,
"preview": "import django.dispatch\n\n# Return Truthy values to enable a specific request.\n# This allows users to build custom logic i"
},
{
"path": "corsheaders/tests.py",
"chars": 21078,
"preview": "from django.conf.urls import url\nfrom django.http import HttpResponse\nfrom django.test import TestCase\nfrom corsheaders."
},
{
"path": "flake8.cfg",
"chars": 75,
"preview": "[flake8]\nmax-complexity=12\nexclude=tests.py,.tox,*.egg\nmax-line-length=120\n"
},
{
"path": "setup.cfg",
"chars": 40,
"preview": "[metadata]\ndescription-file = README.rst"
},
{
"path": "setup.py",
"chars": 1594,
"preview": "#!/usr/bin/env python\n\nfrom corsheaders import __version__\nfrom setuptools import setup, find_packages\n\nsetup(\n name="
},
{
"path": "tests.py",
"chars": 1229,
"preview": "#!/usr/bin/env python\n\"\"\"\n\"\"\"\nimport sys\n\n\ndef run_tests():\n import django\n from django.conf import global_setting"
},
{
"path": "tox.ini",
"chars": 541,
"preview": "[tox]\ndownloadcache = {toxworkdir}/cache/\nenvlist =\n py{27,34,35,36,37}-django110\n py{27,34,35,36,37}-django111\n\n "
}
]
About this extraction
This page contains the full source code of the zestedesavoir/django-cors-middleware GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 20 files (35.9 KB), approximately 8.6k tokens, and a symbol index with 55 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.