master 50d07ca143ea cached
20 files
35.9 KB
8.6k tokens
55 symbols
1 requests
Download .txt
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
Download .txt
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
Download .txt
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.

Copied to clipboard!