Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix request path normalization #272

Merged
merged 5 commits into from Aug 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 12 additions & 11 deletions .travis.yml
Expand Up @@ -7,23 +7,24 @@ 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
exclude:
- python: 3.4
- env:
- DEPEENDENCIES="flask==1.1"

env:
- FLASK=0.10.1
- FLASK=0.10
- 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
- pip install -U setuptools pep8 six coverage docutils pygments packaging $DEPEENDENCIES

script:
- coverage erase
Expand Down
2 changes: 1 addition & 1 deletion examples/app_based_example.py
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions flask_cors/extension.py
Expand Up @@ -10,6 +10,10 @@
"""
from flask import request
from .core import *
try:
from urllib.parse import unquote_plus
except ImportError:
from urllib import unquote_plus

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -173,9 +177,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)
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -33,7 +33,8 @@
platforms='any',
install_requires=install_requires,
tests_require=[
'nose'
'nose',
'packaging'
],
test_suite='nose.collector',
classifiers=[
Expand Down
7 changes: 7 additions & 0 deletions tests/decorator/test_exception_interception.py
Expand Up @@ -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 *
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion tests/extension/test_app_extension.py
Expand Up @@ -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')

Expand All @@ -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'):
Expand Down