From dc23194a86f16492d96f7d630e03fb3b01535e6c Mon Sep 17 00:00:00 2001
From: Cory Dolphin <cory@nextdoor.com>
Date: Sat, 29 Aug 2020 16:48:27 -0600
Subject: [PATCH 1/5] Fix request path normalization

---
 flask_cors/extension.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flask_cors/extension.py b/flask_cors/extension.py
index 6a585aa..3f9f52a 100644
--- a/flask_cors/extension.py
+++ b/flask_cors/extension.py
@@ -10,7 +10,7 @@
 """
 from flask import request
 from .core import *
-
+from urllib.parse import unquote_plus
 LOG = logging.getLogger(__name__)
 
 class CORS(object):
@@ -173,9 +173,9 @@ def cors_after_request(resp):
         if resp.headers is not None and resp.headers.get(ACL_ORIGIN):
             LOG.debug('CORS have been already evaluated, skipping')
             return resp
-
+        normalized_path = unquote_plus(request.path)
         for res_regex, res_options in resources:
-            if try_match(request.path, res_regex):
+            if try_match(normalized_path, res_regex):
                 LOG.debug("Request to '%s' matches CORS resource '%s'. Using options: %s",
                       request.path, get_regexp_pattern(res_regex), res_options)
                 set_cors_headers(resp, res_options)

From 53e284dc873d1260f5de1262a6e24f9d0783aa86 Mon Sep 17 00:00:00 2001
From: Cory Dolphin <cory@nextdoor.com>
Date: Sun, 30 Aug 2020 13:59:37 -0600
Subject: [PATCH 2/5] Fix import

---
 flask_cors/extension.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/flask_cors/extension.py b/flask_cors/extension.py
index 3f9f52a..466869e 100644
--- a/flask_cors/extension.py
+++ b/flask_cors/extension.py
@@ -10,7 +10,11 @@
 """
 from flask import request
 from .core import *
-from urllib.parse import unquote_plus
+try:
+    from urllib.parse import unquote_plus
+except ImportError:
+    from urllib import unquote_plus
+
 LOG = logging.getLogger(__name__)
 
 class CORS(object):

From c3eeda5f56e18eacc0758028350c1cbcc4c9b4b2 Mon Sep 17 00:00:00 2001
From: Cory Dolphin <cory@nextdoor.com>
Date: Sun, 30 Aug 2020 14:13:25 -0600
Subject: [PATCH 3/5] Fix travis file due to flask dependency change

---
 .travis.yml                                   | 20 +++++++------------
 examples/app_based_example.py                 |  2 +-
 setup.py                                      |  3 ++-
 .../decorator/test_exception_interception.py  |  7 +++++++
 tests/extension/test_app_extension.py         |  6 +++++-
 5 files changed, 22 insertions(+), 16 deletions(-)

#diff --git a/.travis.yml b/.travis.yml
#index 5884719..d480429 100644
#--- a/.travis.yml
#+++ b/.travis.yml
#@@ -7,23 +7,17 @@ python:
#   - '3.4'
#   - '3.5'
#   - '3.6'
#+  - '3.7'
#+  - '3.8'
#   - pypy
#-
#-# from https://github.com/travis-ci/travis-ci/issues/9815
#-# https://github.com/travis-ci/travis-ci/issues/9069#issuecomment-425720905
#-# Enable 3.7 without globally enabling sudo and dist: xenial for other build jobs
#-matrix:
#-  include:
#-    - python: 3.7
#-      dist: xenial
#-      sudo: true
#       
# env:
#-- FLASK=0.10.1
#-- FLASK=0.10
#-
#+- FLASK=0.10.1 WERKZEUG_DEP="werkzeug==0.16.1"
#+- FLASK=0.10 WERKZEUG_DEP="werkzeug==0.16.1"
#+- FLASK=1.0 WERKZEUG_DEP=""
#+- FLASK=1.1 WERKZEUG_DEP=""
# install:
#-  - pip install -U setuptools pep8 six coverage docutils pygments flask==$FLASK
#+  - pip install -U setuptools pep8 six coverage docutils pygments flask==$FLASK $WERKZEUG_DEP
# 
# script:
#   - coverage erase
diff --git a/examples/app_based_example.py b/examples/app_based_example.py
index e616aa6..b5ff821 100644
--- a/examples/app_based_example.py
+++ b/examples/app_based_example.py
@@ -124,7 +124,7 @@ def get_exception():
         Browsers will first make a preflight request to verify that the resource
         allows cross-origin POSTs with a JSON Content-Type, which can be simulated
         as:
-        $ curl --include -X OPTIONS http://127.0.0.1:5000/exception \
+        $ curl --include -X OPTIONS http://127.0.0.1:5000/api/exception \
             --header Access-Control-Request-Method:POST \
             --header Access-Control-Request-Headers:Content-Type \
             --header Origin:www.examplesite.com
diff --git a/setup.py b/setup.py
index 32e7999..d117d96 100644
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,8 @@
     platforms='any',
     install_requires=install_requires,
     tests_require=[
-        'nose'
+        'nose',
+        'packaging'
     ],
     test_suite='nose.collector',
     classifiers=[
diff --git a/tests/decorator/test_exception_interception.py b/tests/decorator/test_exception_interception.py
index 87fc04f..fe42d3d 100644
--- a/tests/decorator/test_exception_interception.py
+++ b/tests/decorator/test_exception_interception.py
@@ -8,6 +8,10 @@
     :copyright: (c) 2016 by Cory Dolphin.
     :license: MIT, see LICENSE for more details.
 """
+import unittest
+
+import flask
+from packaging import version
 from ..base_test import FlaskCorsTestCase
 from flask import Flask, abort
 from flask_cors import *
@@ -198,6 +202,9 @@ def get_with_origins(path):
             self.assertEqual(resp.status_code, 200)
             self.assertFalse(ACL_ORIGIN in resp.headers)
 
+    @unittest.skipIf(version.parse(flask.__version__) >= version.parse("1.1"),
+                     "Flask 1.1 changed interception behavior, so after request handlers are always run. "
+                     "This obviates the need for our hacky interception")
     def test_acl_uncaught_exception_500(self):
         '''
             Uncaught exceptions will trigger Flask's internal exception
diff --git a/tests/extension/test_app_extension.py b/tests/extension/test_app_extension.py
index 6ebca5f..597b744 100644
--- a/tests/extension/test_app_extension.py
+++ b/tests/extension/test_app_extension.py
@@ -204,7 +204,7 @@ class AppExtensionString(FlaskCorsTestCase):
     def setUp(self):
         self.app = Flask(__name__)
         CORS(self.app, resources=r'/api/*',
-             headers='Content-Type',
+             allow_headers='Content-Type',
              expose_headers='X-Total-Count',
              origins='http://bar.com')
 
@@ -225,6 +225,10 @@ def overridden():
         def index():
             return 'Welcome'
 
+        @self.app.route('/foo.txt')
+        def foo_txt():
+            return 'Welcome'
+
     def test_exposed(self):
         for path in '/api/v1/foo', '/api/v1/bar':
             for resp in self.iter_responses(path, origin='http://bar.com'):

#From b83295c9049097b1dbee0465218953fd75d62023 Mon Sep 17 00:00:00 2001
#From: Cory Dolphin <cory@nextdoor.com>
#Date: Sun, 30 Aug 2020 15:15:53 -0600
#Subject: [PATCH 4/5] Refactor travis file
#
#---
# .travis.yml | 19 +++++++++++++------
# 1 file changed, 13 insertions(+), 6 deletions(-)
#
#diff --git a/.travis.yml b/.travis.yml
#index d480429..4f8d3b4 100644
#--- a/.travis.yml
#+++ b/.travis.yml
#@@ -10,14 +10,21 @@ python:
#   - '3.7'
#   - '3.8'
#   - pypy
#-      
#+
#+matrix:
#+  exclude:
#+    - python: 3.4
#+    - env:
#+        - DEPEENDENCIES="flask==1.1"
#+
# env:
#-- FLASK=0.10.1 WERKZEUG_DEP="werkzeug==0.16.1"
#-- FLASK=0.10 WERKZEUG_DEP="werkzeug==0.16.1"
#-- FLASK=1.0 WERKZEUG_DEP=""
#-- FLASK=1.1 WERKZEUG_DEP=""
#+- DEPEENDENCIES="flask==0.10.1 werkzeug==0.16.1" # pin werkzeug for Flask 10, 10.1 since Flask does not pin it itself.
#+- DEPEENDENCIES="flask==0.10 werkzeug==0.16.1"
#+- DEPEENDENCIES="flask==1.0"
#+- DEPEENDENCIES="flask==1.1"
#+
# install:
#-  - pip install -U setuptools pep8 six coverage docutils pygments flask==$FLASK $WERKZEUG_DEP
#+  - pip install -U setuptools pep8 six coverage docutils pygments $DEPEENDENCIES
# 
# script:
#   - coverage erase
#
#From de439b5146e27a4fbf6b5653d17ba3b4eb9a4ab2 Mon Sep 17 00:00:00 2001
#From: Cory Dolphin <cory@nextdoor.com>
#Date: Sun, 30 Aug 2020 15:21:37 -0600
#Subject: [PATCH 5/5] Include packaging
#
#---
# .travis.yml | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)
#
#diff --git a/.travis.yml b/.travis.yml
#index 4f8d3b4..cf26ab2 100644
#--- a/.travis.yml
#+++ b/.travis.yml
#@@ -24,7 +24,7 @@ env:
# - DEPEENDENCIES="flask==1.1"
# 
# install:
#-  - pip install -U setuptools pep8 six coverage docutils pygments $DEPEENDENCIES
#+  - pip install -U setuptools pep8 six coverage docutils pygments packaging $DEPEENDENCIES
# 
# script:
#   - coverage erase
