Refs #23919 -- Replaced usage of django.utils.http utilities with Python equivalents
Thanks Tim Graham for the review.
This commit is contained in:
parent
af598187ec
commit
fee42fd99e
|
@ -3,6 +3,7 @@ import json
|
||||||
import operator
|
import operator
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functools import partial, reduce, update_wrapper
|
from functools import partial, reduce, update_wrapper
|
||||||
|
from urllib.parse import quote as urlquote
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -39,7 +40,7 @@ from django.urls import reverse
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.http import urlencode, urlquote
|
from django.utils.http import urlencode
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.text import capfirst, format_lazy, get_text_list
|
from django.utils.text import capfirst, format_lazy, get_text_list
|
||||||
from django.utils.translation import ugettext as _, ungettext
|
from django.utils.translation import ugettext as _, ungettext
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.http import urlquote
|
|
||||||
|
|
||||||
TEMPLATE_FRAGMENT_KEY_TEMPLATE = 'template.cache.%s.%s'
|
TEMPLATE_FRAGMENT_KEY_TEMPLATE = 'template.cache.%s.%s'
|
||||||
|
|
||||||
|
@ -9,6 +9,6 @@ TEMPLATE_FRAGMENT_KEY_TEMPLATE = 'template.cache.%s.%s'
|
||||||
def make_template_fragment_key(fragment_name, vary_on=None):
|
def make_template_fragment_key(fragment_name, vary_on=None):
|
||||||
if vary_on is None:
|
if vary_on is None:
|
||||||
vary_on = ()
|
vary_on = ()
|
||||||
key = ':'.join(urlquote(var) for var in vary_on)
|
key = ':'.join(quote(str(var)) for var in vary_on)
|
||||||
args = hashlib.md5(force_bytes(key))
|
args = hashlib.md5(force_bytes(key))
|
||||||
return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, args.hexdigest())
|
return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, args.hexdigest())
|
||||||
|
|
|
@ -5,6 +5,7 @@ from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from django.utils import formats
|
from django.utils import formats
|
||||||
from django.utils.dateformat import format, time_format
|
from django.utils.dateformat import format, time_format
|
||||||
|
@ -13,7 +14,6 @@ from django.utils.html import (
|
||||||
avoid_wrapping, conditional_escape, escape, escapejs, linebreaks,
|
avoid_wrapping, conditional_escape, escape, escapejs, linebreaks,
|
||||||
strip_tags, urlize as _urlize,
|
strip_tags, urlize as _urlize,
|
||||||
)
|
)
|
||||||
from django.utils.http import urlquote
|
|
||||||
from django.utils.safestring import SafeData, mark_safe
|
from django.utils.safestring import SafeData, mark_safe
|
||||||
from django.utils.text import (
|
from django.utils.text import (
|
||||||
Truncator, normalize_newlines, phone2numeric, slugify as _slugify, wrap,
|
Truncator, normalize_newlines, phone2numeric, slugify as _slugify, wrap,
|
||||||
|
@ -318,14 +318,14 @@ def urlencode(value, safe=None):
|
||||||
Escapes a value for use in a URL.
|
Escapes a value for use in a URL.
|
||||||
|
|
||||||
Takes an optional ``safe`` parameter used to determine the characters which
|
Takes an optional ``safe`` parameter used to determine the characters which
|
||||||
should not be escaped by Django's ``urlquote`` method. If not provided, the
|
should not be escaped by Python's quote() function. If not provided, the
|
||||||
default safe characters will be used (but an empty string can be provided
|
default safe characters will be used (but an empty string can be provided
|
||||||
when *all* characters should be escaped).
|
when *all* characters should be escaped).
|
||||||
"""
|
"""
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if safe is not None:
|
if safe is not None:
|
||||||
kwargs['safe'] = safe
|
kwargs['safe'] = safe
|
||||||
return urlquote(value, **kwargs)
|
return quote(value, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@register.filter(is_safe=True, needs_autoescape=True)
|
@register.filter(is_safe=True, needs_autoescape=True)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import functools
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.checks import Warning
|
from django.core.checks import Warning
|
||||||
|
@ -17,7 +18,7 @@ from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.http import RFC3986_SUBDELIMS, urlquote
|
from django.utils.http import RFC3986_SUBDELIMS
|
||||||
from django.utils.regex_helper import normalize
|
from django.utils.regex_helper import normalize
|
||||||
from django.utils.translation import get_language
|
from django.utils.translation import get_language
|
||||||
|
|
||||||
|
@ -455,7 +456,7 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||||
candidate_pat = _prefix.replace('%', '%%') + result
|
candidate_pat = _prefix.replace('%', '%%') + result
|
||||||
if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs):
|
if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs):
|
||||||
# safe characters from `pchar` definition of RFC 3986
|
# safe characters from `pchar` definition of RFC 3986
|
||||||
url = urlquote(candidate_pat % candidate_subs, safe=RFC3986_SUBDELIMS + str('/~:@'))
|
url = quote(candidate_pat % candidate_subs, safe=RFC3986_SUBDELIMS + '/~:@')
|
||||||
# Don't allow construction of scheme relative urls.
|
# Don't allow construction of scheme relative urls.
|
||||||
if url.startswith('//'):
|
if url.startswith('//'):
|
||||||
url = '/%%2F%s' % url[2:]
|
url = '/%%2F%s' % url[2:]
|
||||||
|
|
|
@ -14,7 +14,7 @@ from urllib.parse import (
|
||||||
from django.core.exceptions import TooManyFieldsSent
|
from django.core.exceptions import TooManyFieldsSent
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.deprecation import RemovedInDjango21Warning
|
from django.utils.deprecation import RemovedInDjango21Warning
|
||||||
from django.utils.encoding import force_bytes, force_str, force_text
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.functional import keep_lazy_text
|
from django.utils.functional import keep_lazy_text
|
||||||
|
|
||||||
# based on RFC 7232, Appendix C
|
# based on RFC 7232, Appendix C
|
||||||
|
@ -47,58 +47,53 @@ FIELDS_MATCH = re.compile('[&;]')
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def urlquote(url, safe='/'):
|
def urlquote(url, safe='/'):
|
||||||
"""
|
"""
|
||||||
A version of Python's urllib.quote() function that can operate on unicode
|
A legacy compatibility wrapper to Python's urllib.parse.quote() function.
|
||||||
strings. The url is first UTF-8 encoded before quoting. The returned string
|
(was used for unicode handling on Python 2)
|
||||||
can safely be used as part of an argument to a subsequent iri_to_uri() call
|
|
||||||
without double-quoting occurring.
|
|
||||||
"""
|
"""
|
||||||
return force_text(quote(force_str(url), force_str(safe)))
|
return quote(url, safe)
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def urlquote_plus(url, safe=''):
|
def urlquote_plus(url, safe=''):
|
||||||
"""
|
"""
|
||||||
A version of Python's urllib.quote_plus() function that can operate on
|
A legacy compatibility wrapper to Python's urllib.parse.quote_plus()
|
||||||
unicode strings. The url is first UTF-8 encoded before quoting. The
|
function. (was used for unicode handling on Python 2)
|
||||||
returned string can safely be used as part of an argument to a subsequent
|
|
||||||
iri_to_uri() call without double-quoting occurring.
|
|
||||||
"""
|
"""
|
||||||
return force_text(quote_plus(force_str(url), force_str(safe)))
|
return quote_plus(url, safe)
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def urlunquote(quoted_url):
|
def urlunquote(quoted_url):
|
||||||
"""
|
"""
|
||||||
A wrapper for Python's urllib.unquote() function that can operate on
|
A legacy compatibility wrapper to Python's urllib.parse.unquote() function.
|
||||||
the result of django.utils.http.urlquote().
|
(was used for unicode handling on Python 2)
|
||||||
"""
|
"""
|
||||||
return force_text(unquote(force_str(quoted_url)))
|
return unquote(quoted_url)
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def urlunquote_plus(quoted_url):
|
def urlunquote_plus(quoted_url):
|
||||||
"""
|
"""
|
||||||
A wrapper for Python's urllib.unquote_plus() function that can operate on
|
A legacy compatibility wrapper to Python's urllib.parse.unquote_plus()
|
||||||
the result of django.utils.http.urlquote_plus().
|
function. (was used for unicode handling on Python 2)
|
||||||
"""
|
"""
|
||||||
return force_text(unquote_plus(force_str(quoted_url)))
|
return unquote_plus(quoted_url)
|
||||||
|
|
||||||
|
|
||||||
def urlencode(query, doseq=0):
|
def urlencode(query, doseq=False):
|
||||||
"""
|
"""
|
||||||
A version of Python's urllib.urlencode() function that can operate on
|
A version of Python's urllib.parse.urlencode() function that can operate on
|
||||||
unicode strings. The parameters are first cast to UTF-8 encoded strings and
|
MultiValueDict and non-string values.
|
||||||
then encoded as per normal.
|
|
||||||
"""
|
"""
|
||||||
if isinstance(query, MultiValueDict):
|
if isinstance(query, MultiValueDict):
|
||||||
query = query.lists()
|
query = query.lists()
|
||||||
elif hasattr(query, 'items'):
|
elif hasattr(query, 'items'):
|
||||||
query = query.items()
|
query = query.items()
|
||||||
return original_urlencode(
|
return original_urlencode(
|
||||||
[(force_str(k),
|
[(k, [str(i) for i in v] if isinstance(v, (list, tuple)) else str(v))
|
||||||
[force_str(i) for i in v] if isinstance(v, (list, tuple)) else force_str(v))
|
|
||||||
for k, v in query],
|
for k, v in query],
|
||||||
doseq)
|
doseq
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def cookie_date(epoch_seconds=None):
|
def cookie_date(epoch_seconds=None):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -9,7 +10,7 @@ from django.template import Context, Engine
|
||||||
from django.urls import translate_url
|
from django.urls import translate_url
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.formats import get_format
|
from django.utils.formats import get_format
|
||||||
from django.utils.http import is_safe_url, urlunquote
|
from django.utils.http import is_safe_url
|
||||||
from django.utils.translation import (
|
from django.utils.translation import (
|
||||||
LANGUAGE_SESSION_KEY, check_for_language, get_language,
|
LANGUAGE_SESSION_KEY, check_for_language, get_language,
|
||||||
)
|
)
|
||||||
|
@ -35,7 +36,7 @@ def set_language(request):
|
||||||
not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())):
|
not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure())):
|
||||||
next = request.META.get('HTTP_REFERER')
|
next = request.META.get('HTTP_REFERER')
|
||||||
if next:
|
if next:
|
||||||
next = urlunquote(next) # HTTP_REFERER may be encoded.
|
next = unquote(next) # HTTP_REFERER may be encoded.
|
||||||
if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()):
|
if not is_safe_url(url=next, allowed_hosts={request.get_host()}, require_https=request.is_secure()):
|
||||||
next = '/'
|
next = '/'
|
||||||
response = http.HttpResponseRedirect(next) if next else http.HttpResponse(status=204)
|
response = http.HttpResponseRedirect(next) if next else http.HttpResponse(status=204)
|
||||||
|
|
|
@ -156,8 +156,8 @@ Django provides some assistance.
|
||||||
* The function :func:`django.utils.encoding.iri_to_uri()` implements the
|
* The function :func:`django.utils.encoding.iri_to_uri()` implements the
|
||||||
conversion from IRI to URI as required by the specification (:rfc:`3987#section-3.1`).
|
conversion from IRI to URI as required by the specification (:rfc:`3987#section-3.1`).
|
||||||
|
|
||||||
* The functions :func:`django.utils.http.urlquote()` and
|
* The functions ``django.utils.http.urlquote()`` and
|
||||||
:func:`django.utils.http.urlquote_plus()` are versions of Python's standard
|
``django.utils.http.urlquote_plus()`` are versions of Python's standard
|
||||||
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
|
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
|
||||||
characters. (The data is converted to UTF-8 prior to encoding.)
|
characters. (The data is converted to UTF-8 prior to encoding.)
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,8 @@ use for reversing. By default, the root URLconf for the current thread is used.
|
||||||
>>> reverse('cities', args=['Orléans'])
|
>>> reverse('cities', args=['Orléans'])
|
||||||
'.../Orl%C3%A9ans/'
|
'.../Orl%C3%A9ans/'
|
||||||
|
|
||||||
Applying further encoding (such as :meth:`~django.utils.http.urlquote` or
|
Applying further encoding (such as :func:`urllib.parse.quote`) to the output
|
||||||
``urllib.quote``) to the output of ``reverse()`` may produce undesirable
|
of ``reverse()`` may produce undesirable results.
|
||||||
results.
|
|
||||||
|
|
||||||
``reverse_lazy()``
|
``reverse_lazy()``
|
||||||
==================
|
==================
|
||||||
|
|
|
@ -684,27 +684,10 @@ escaping HTML.
|
||||||
.. module:: django.utils.http
|
.. module:: django.utils.http
|
||||||
:synopsis: HTTP helper functions. (URL encoding, cookie handling, ...)
|
:synopsis: HTTP helper functions. (URL encoding, cookie handling, ...)
|
||||||
|
|
||||||
.. function:: urlquote(url, safe='/')
|
|
||||||
|
|
||||||
A version of Python's ``urllib.quote()`` function that can operate on
|
|
||||||
unicode strings. The url is first UTF-8 encoded before quoting. The
|
|
||||||
returned string can safely be used as part of an argument to a subsequent
|
|
||||||
``iri_to_uri()`` call without double-quoting occurring. Employs lazy
|
|
||||||
execution.
|
|
||||||
|
|
||||||
.. function:: urlquote_plus(url, safe='')
|
|
||||||
|
|
||||||
A version of Python's urllib.quote_plus() function that can operate on
|
|
||||||
unicode strings. The url is first UTF-8 encoded before quoting. The
|
|
||||||
returned string can safely be used as part of an argument to a subsequent
|
|
||||||
``iri_to_uri()`` call without double-quoting occurring. Employs lazy
|
|
||||||
execution.
|
|
||||||
|
|
||||||
.. function:: urlencode(query, doseq=0)
|
.. function:: urlencode(query, doseq=0)
|
||||||
|
|
||||||
A version of Python's urllib.urlencode() function that can operate on
|
A version of Python's :func:`urllib.parse.urlencode` function that can
|
||||||
unicode strings. The parameters are first cast to UTF-8 encoded strings
|
operate on ``MultiValueDict`` and non-string values.
|
||||||
and then encoded as per normal.
|
|
||||||
|
|
||||||
.. function:: cookie_date(epoch_seconds=None)
|
.. function:: cookie_date(epoch_seconds=None)
|
||||||
|
|
||||||
|
|
|
@ -585,7 +585,7 @@ be at the end of a line. If they are not, the comments are ignored and
|
||||||
Quoting in ``reverse()``
|
Quoting in ``reverse()``
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
When reversing URLs, Django didn't apply :func:`~django.utils.http.urlquote`
|
When reversing URLs, Django didn't apply ``django.utils.http.urlquote``
|
||||||
to arguments before interpolating them in URL patterns. This bug is fixed in
|
to arguments before interpolating them in URL patterns. This bug is fixed in
|
||||||
Django 1.6. If you worked around this bug by applying URL quoting before
|
Django 1.6. If you worked around this bug by applying URL quoting before
|
||||||
passing arguments to ``reverse()``, this may result in double-quoting. If this
|
passing arguments to ``reverse()``, this may result in double-quoting. If this
|
||||||
|
|
|
@ -3,7 +3,7 @@ import itertools
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from urllib.parse import ParseResult, urlparse
|
from urllib.parse import ParseResult, quote, urlparse
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -28,7 +28,6 @@ from django.test.utils import patch_logger
|
||||||
from django.urls import NoReverseMatch, reverse, reverse_lazy
|
from django.urls import NoReverseMatch, reverse, reverse_lazy
|
||||||
from django.utils.deprecation import RemovedInDjango21Warning
|
from django.utils.deprecation import RemovedInDjango21Warning
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.http import urlquote
|
|
||||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||||
|
|
||||||
from .client import PasswordResetConfirmClient
|
from .client import PasswordResetConfirmClient
|
||||||
|
@ -546,7 +545,7 @@ class LoginTest(AuthViewsTestCase):
|
||||||
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
||||||
'url': login_url,
|
'url': login_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'bad_url': urlquote(bad_url),
|
'bad_url': quote(bad_url),
|
||||||
}
|
}
|
||||||
response = self.client.post(nasty_url, {
|
response = self.client.post(nasty_url, {
|
||||||
'username': 'testclient',
|
'username': 'testclient',
|
||||||
|
@ -568,7 +567,7 @@ class LoginTest(AuthViewsTestCase):
|
||||||
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
||||||
'url': login_url,
|
'url': login_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'good_url': urlquote(good_url),
|
'good_url': quote(good_url),
|
||||||
}
|
}
|
||||||
response = self.client.post(safe_url, {
|
response = self.client.post(safe_url, {
|
||||||
'username': 'testclient',
|
'username': 'testclient',
|
||||||
|
@ -583,7 +582,7 @@ class LoginTest(AuthViewsTestCase):
|
||||||
not_secured_url = '%(url)s?%(next)s=%(next_url)s' % {
|
not_secured_url = '%(url)s?%(next)s=%(next_url)s' % {
|
||||||
'url': login_url,
|
'url': login_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'next_url': urlquote(non_https_next_url),
|
'next_url': quote(non_https_next_url),
|
||||||
}
|
}
|
||||||
post_data = {
|
post_data = {
|
||||||
'username': 'testclient',
|
'username': 'testclient',
|
||||||
|
@ -701,13 +700,13 @@ class LoginURLSettings(AuthViewsTestCase):
|
||||||
|
|
||||||
@override_settings(LOGIN_URL='http://remote.example.com/login')
|
@override_settings(LOGIN_URL='http://remote.example.com/login')
|
||||||
def test_remote_login_url(self):
|
def test_remote_login_url(self):
|
||||||
quoted_next = urlquote('http://testserver/login_required/')
|
quoted_next = quote('http://testserver/login_required/')
|
||||||
expected = 'http://remote.example.com/login?next=%s' % quoted_next
|
expected = 'http://remote.example.com/login?next=%s' % quoted_next
|
||||||
self.assertLoginURLEquals(expected)
|
self.assertLoginURLEquals(expected)
|
||||||
|
|
||||||
@override_settings(LOGIN_URL='https:///login/')
|
@override_settings(LOGIN_URL='https:///login/')
|
||||||
def test_https_login_url(self):
|
def test_https_login_url(self):
|
||||||
quoted_next = urlquote('http://testserver/login_required/')
|
quoted_next = quote('http://testserver/login_required/')
|
||||||
expected = 'https:///login/?next=%s' % quoted_next
|
expected = 'https:///login/?next=%s' % quoted_next
|
||||||
self.assertLoginURLEquals(expected)
|
self.assertLoginURLEquals(expected)
|
||||||
|
|
||||||
|
@ -717,7 +716,7 @@ class LoginURLSettings(AuthViewsTestCase):
|
||||||
|
|
||||||
@override_settings(LOGIN_URL='http://remote.example.com/login/?next=/default/')
|
@override_settings(LOGIN_URL='http://remote.example.com/login/?next=/default/')
|
||||||
def test_remote_login_url_with_next_querystring(self):
|
def test_remote_login_url_with_next_querystring(self):
|
||||||
quoted_next = urlquote('http://testserver/login_required/')
|
quoted_next = quote('http://testserver/login_required/')
|
||||||
expected = 'http://remote.example.com/login/?next=%s' % quoted_next
|
expected = 'http://remote.example.com/login/?next=%s' % quoted_next
|
||||||
self.assertLoginURLEquals(expected)
|
self.assertLoginURLEquals(expected)
|
||||||
|
|
||||||
|
@ -973,7 +972,7 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
|
||||||
'url': logout_url,
|
'url': logout_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'bad_url': urlquote(bad_url),
|
'bad_url': quote(bad_url),
|
||||||
}
|
}
|
||||||
self.login()
|
self.login()
|
||||||
response = self.client.get(nasty_url)
|
response = self.client.get(nasty_url)
|
||||||
|
@ -994,7 +993,7 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
|
||||||
'url': logout_url,
|
'url': logout_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'good_url': urlquote(good_url),
|
'good_url': quote(good_url),
|
||||||
}
|
}
|
||||||
self.login()
|
self.login()
|
||||||
response = self.client.get(safe_url)
|
response = self.client.get(safe_url)
|
||||||
|
@ -1008,7 +1007,7 @@ class LogoutTest(AuthViewsTestCase):
|
||||||
url = '%(url)s?%(next)s=%(next_url)s' % {
|
url = '%(url)s?%(next)s=%(next_url)s' % {
|
||||||
'url': logout_url,
|
'url': logout_url,
|
||||||
'next': REDIRECT_FIELD_NAME,
|
'next': REDIRECT_FIELD_NAME,
|
||||||
'next_url': urlquote(non_https_next_url),
|
'next_url': quote(non_https_next_url),
|
||||||
}
|
}
|
||||||
self.login()
|
self.login()
|
||||||
response = self.client.get(url, secure=True)
|
response = self.client.get(url, secure=True)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from django.contrib.contenttypes.fields import (
|
from django.contrib.contenttypes.fields import (
|
||||||
GenericForeignKey, GenericRelation,
|
GenericForeignKey, GenericRelation,
|
||||||
)
|
)
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.sites.models import SiteManager
|
from django.contrib.sites.models import SiteManager
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.http import urlquote
|
|
||||||
|
|
||||||
|
|
||||||
class Site(models.Model):
|
class Site(models.Model):
|
||||||
|
@ -72,7 +73,7 @@ class FooWithUrl(FooWithoutUrl):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return "/users/%s/" % urlquote(self.name)
|
return "/users/%s/" % quote(self.name)
|
||||||
|
|
||||||
|
|
||||||
class FooWithBrokenAbsoluteUrl(FooWithoutUrl):
|
class FooWithBrokenAbsoluteUrl(FooWithoutUrl):
|
||||||
|
@ -126,4 +127,4 @@ class ModelWithNullFKToSite(models.Model):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return '/title/%s/' % urlquote(self.title)
|
return '/title/%s/' % quote(self.title)
|
||||||
|
|
|
@ -7,13 +7,13 @@ import sys
|
||||||
import tempfile as sys_tempfile
|
import tempfile as sys_tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from io import BytesIO, StringIO
|
from io import BytesIO, StringIO
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from django.core.files import temp as tempfile
|
from django.core.files import temp as tempfile
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.http.multipartparser import MultiPartParser, parse_header
|
from django.http.multipartparser import MultiPartParser, parse_header
|
||||||
from django.test import SimpleTestCase, TestCase, client, override_settings
|
from django.test import SimpleTestCase, TestCase, client, override_settings
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.http import urlquote
|
|
||||||
|
|
||||||
from . import uploadhandler
|
from . import uploadhandler
|
||||||
from .models import FileModel
|
from .models import FileModel
|
||||||
|
@ -127,7 +127,7 @@ class FileUploadTests(TestCase):
|
||||||
payload = client.FakePayload()
|
payload = client.FakePayload()
|
||||||
payload.write('\r\n'.join([
|
payload.write('\r\n'.join([
|
||||||
'--' + client.BOUNDARY,
|
'--' + client.BOUNDARY,
|
||||||
'Content-Disposition: form-data; name="file_unicode"; filename*=UTF-8\'\'%s' % urlquote(UNICODE_FILENAME),
|
'Content-Disposition: form-data; name="file_unicode"; filename*=UTF-8\'\'%s' % quote(UNICODE_FILENAME),
|
||||||
'Content-Type: application/octet-stream',
|
'Content-Type: application/octet-stream',
|
||||||
'',
|
'',
|
||||||
'You got pwnd.\r\n',
|
'You got pwnd.\r\n',
|
||||||
|
@ -153,7 +153,7 @@ class FileUploadTests(TestCase):
|
||||||
payload.write(
|
payload.write(
|
||||||
'\r\n'.join([
|
'\r\n'.join([
|
||||||
'--' + client.BOUNDARY,
|
'--' + client.BOUNDARY,
|
||||||
'Content-Disposition: form-data; name*=UTF-8\'\'file_unicode; filename*=UTF-8\'\'%s' % urlquote(
|
'Content-Disposition: form-data; name*=UTF-8\'\'file_unicode; filename*=UTF-8\'\'%s' % quote(
|
||||||
UNICODE_FILENAME
|
UNICODE_FILENAME
|
||||||
),
|
),
|
||||||
'Content-Type: application/octet-stream',
|
'Content-Type: application/octet-stream',
|
||||||
|
|
|
@ -3,7 +3,7 @@ from datetime import datetime, timedelta
|
||||||
from http import cookies
|
from http import cookies
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from urllib.parse import urlencode as original_urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.core.handlers.wsgi import LimitedStream, WSGIRequest
|
from django.core.handlers.wsgi import LimitedStream, WSGIRequest
|
||||||
|
@ -14,7 +14,7 @@ from django.http.request import split_domain_port
|
||||||
from django.test import RequestFactory, SimpleTestCase, override_settings
|
from django.test import RequestFactory, SimpleTestCase, override_settings
|
||||||
from django.test.client import FakePayload
|
from django.test.client import FakePayload
|
||||||
from django.test.utils import freeze_time
|
from django.test.utils import freeze_time
|
||||||
from django.utils.http import cookie_date, urlencode
|
from django.utils.http import cookie_date
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ class RequestsTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Test a POST with non-utf-8 payload encoding.
|
Test a POST with non-utf-8 payload encoding.
|
||||||
"""
|
"""
|
||||||
payload = FakePayload(original_urlencode({'key': 'España'.encode('latin-1')}))
|
payload = FakePayload(urlencode({'key': 'España'.encode('latin-1')}))
|
||||||
request = WSGIRequest({
|
request = WSGIRequest({
|
||||||
'REQUEST_METHOD': 'POST',
|
'REQUEST_METHOD': 'POST',
|
||||||
'CONTENT_LENGTH': len(payload),
|
'CONTENT_LENGTH': len(payload),
|
||||||
|
|
|
@ -5,10 +5,10 @@ import errno
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
|
from urllib.parse import urlencode
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
from django.test import LiveServerTestCase, override_settings
|
from django.test import LiveServerTestCase, override_settings
|
||||||
from django.utils.http import urlencode
|
|
||||||
|
|
||||||
from .models import Person
|
from .models import Person
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import datetime
|
import datetime
|
||||||
import unittest
|
import unittest
|
||||||
|
from urllib.parse import quote_plus
|
||||||
|
|
||||||
from django.utils.encoding import (
|
from django.utils.encoding import (
|
||||||
escape_uri_path, filepath_to_uri, force_bytes, force_text, iri_to_uri,
|
escape_uri_path, filepath_to_uri, force_bytes, force_text, iri_to_uri,
|
||||||
smart_text, uri_to_iri,
|
smart_text, uri_to_iri,
|
||||||
)
|
)
|
||||||
from django.utils.functional import SimpleLazyObject
|
from django.utils.functional import SimpleLazyObject
|
||||||
from django.utils.http import urlquote_plus
|
|
||||||
|
|
||||||
|
|
||||||
class TestEncodingUtils(unittest.TestCase):
|
class TestEncodingUtils(unittest.TestCase):
|
||||||
|
@ -72,7 +72,7 @@ class TestRFC3987IEncodingUtils(unittest.TestCase):
|
||||||
# Valid UTF-8 sequences are encoded.
|
# Valid UTF-8 sequences are encoded.
|
||||||
('red%09rosé#red', 'red%09ros%C3%A9#red'),
|
('red%09rosé#red', 'red%09ros%C3%A9#red'),
|
||||||
('/blog/for/Jürgen Münster/', '/blog/for/J%C3%BCrgen%20M%C3%BCnster/'),
|
('/blog/for/Jürgen Münster/', '/blog/for/J%C3%BCrgen%20M%C3%BCnster/'),
|
||||||
('locations/%s' % urlquote_plus('Paris & Orléans'), 'locations/Paris+%26+Orl%C3%A9ans'),
|
('locations/%s' % quote_plus('Paris & Orléans'), 'locations/Paris+%26+Orl%C3%A9ans'),
|
||||||
|
|
||||||
# Reserved chars remain unescaped.
|
# Reserved chars remain unescaped.
|
||||||
('%&', '%&'),
|
('%&', '%&'),
|
||||||
|
|
Loading…
Reference in New Issue