Skip to content

Commit

Permalink
feat: Introduced new REVPROXY_QUOTE_SPACES_AS_PLUS setting (#191)
Browse files Browse the repository at this point in the history
* feat: declared new revproxy settings section

* feat: allow both quote and quote_plus depending on QUOTE_SPACES_AS_PLUS setting

* chore: added test

* chore: renamed variable

* chore: updated docs

---------

Co-authored-by: andruten <[email protected]>
  • Loading branch information
andruten and andruten authored Oct 28, 2024
1 parent bf8b4f7 commit feb7849
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
0.13.0 (Unreleased)
===================

* Added new `REVPROXY_QUOTE_SPACES_AS_PLUS` setting


0.12.0 (2023-10-19)
===================

Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Contents:
quickstart
proxyview
modules
settings
changelog


Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Start by adding revproxy to your ``settings.py`` file as follows:
INSTALLED_APPS = (
# ...
'django.contrib.auth',
'revproxy',
'revproxy.apps.RevProxyConfig',
# ...
)
Expand Down
4 changes: 4 additions & 0 deletions docs/settings.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Settings
==================

`REVPROXY_QUOTE_SPACES_AS_PLUS`: Tells revproxy if it spaces should be replaced by `+` or `%20`.
2 changes: 2 additions & 0 deletions revproxy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
__version__ = '0.12.0'

default_app_config = 'revproxy.apps.RevProxyConfig'
18 changes: 18 additions & 0 deletions revproxy/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.apps import AppConfig
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from .settings import REVPROXY_DEFAULT_SETTINGS


class RevProxyConfig(AppConfig):
name = 'revproxy'
verbose_name = _('Revproxy')

def ready(self):
super().ready()
for setting, default_value in REVPROXY_DEFAULT_SETTINGS.items():
setattr(
settings,
setting,
getattr(settings, setting, default_value),
)
3 changes: 3 additions & 0 deletions revproxy/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
REVPROXY_DEFAULT_SETTINGS = {
'REVPROXY_QUOTE_SPACES_AS_PLUS': True,
}
13 changes: 10 additions & 3 deletions revproxy/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@

try:
from django.utils.six.moves.urllib.parse import (
urlparse, urlencode, quote_plus)
urlparse, urlencode, quote_plus, quote
)
except ImportError:
# Django 3 has no six
from urllib.parse import urlparse, urlencode, quote_plus
from urllib.parse import (
urlparse, urlencode, quote_plus, quote
)

from django.conf import settings
from django.shortcuts import redirect
from django.views.generic import View
from django.utils.decorators import classonlymethod
Expand Down Expand Up @@ -165,7 +169,10 @@ def get_request_headers(self):

def get_quoted_path(self, path):
"""Return quoted path to be used in proxied request"""
return quote_plus(path.encode('utf8'), QUOTE_SAFE)
if settings.REVPROXY_QUOTE_SPACES_AS_PLUS:
return quote_plus(path.encode('utf8'), QUOTE_SAFE)
else:
return quote(path.encode('utf8'), QUOTE_SAFE)

def get_encoded_query_params(self):
"""Return encoded query params to be used in proxied request"""
Expand Down
23 changes: 21 additions & 2 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from unittest.mock import patch

from django.conf import settings
from django.test import TestCase, RequestFactory
from django.test import TestCase, RequestFactory, override_settings
try:
from django.utils.six.moves.urllib.parse import ParseResult
except ImportError:
Expand Down Expand Up @@ -194,7 +194,7 @@ class CustomProxyView(ProxyView):
decode_content=False,
headers=headers)

def test_space_is_escaped(self):
def test_space_is_escaped_enabled(self):
class CustomProxyView(ProxyView):
upstream = 'http://example.com'

Expand All @@ -212,6 +212,25 @@ class CustomProxyView(ProxyView):
decode_content=False,
headers=headers)

@override_settings(REVPROXY_QUOTE_SPACES_AS_PLUS=False)
def test_space_is_escaped_disabled(self):
class CustomProxyView(ProxyView):
upstream = 'http://example.com'

path = ' test test'
request = self.factory.get(path)
CustomProxyView.as_view()(request, path)

url = 'http://example.com/%20test%20test'
headers = {u'Cookie': u''}
self.urlopen.assert_called_with('GET', url,
body=b'',
redirect=False,
retries=None,
preload_content=False,
decode_content=False,
headers=headers)

def test_extending_headers(self):
class CustomProxyView(ProxyView):
upstream = 'http://example.com'
Expand Down

0 comments on commit feb7849

Please sign in to comment.