make the query string uri-safe before redirects (bug 564820)

This commit is contained in:
Jeff Balogh 2010-05-24 13:19:55 -07:00
Родитель 53fbc15d79
Коммит 896cfa62e7
4 изменённых файлов: 37 добавлений и 8 удалений

Просмотреть файл

@ -376,3 +376,9 @@ def test_button_caching():
fmt = '%a, %d %b %Y %H:%M:%S GMT'
expires = datetime.strptime(response['Expires'], fmt)
assert (expires - datetime.now()).days >= 365
def test_unicode_redirect():
url = '/en-US/firefox/addon/2848?xx=\xc2\xbcwhscheck\xc2\xbe'
response = test.Client().get(url)
eq_(response.status_code, 301)

Просмотреть файл

@ -3,12 +3,13 @@ Borrowed from: http://code.google.com/p/django-localeurl
Note: didn't make sense to use localeurl since we need to capture app as well
"""
import contextlib
import urllib
from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpResponsePermanentRedirect, QueryDict
from django.http import HttpResponsePermanentRedirect
from django.middleware import common
from django.utils.encoding import smart_str
from django.utils.encoding import iri_to_uri, smart_str
import tower
@ -102,7 +103,31 @@ class RemoveSlashMiddleware(object):
# Use request.path because we munged app/locale in path_info.
newurl = request.path[:-1]
if request.GET:
newurl += '?' + request.META['QUERY_STRING']
with safe_query_string(request):
newurl += '?' + request.META['QUERY_STRING']
return HttpResponsePermanentRedirect(newurl)
else:
return response
@contextlib.contextmanager
def safe_query_string(request):
"""
Turn the QUERY_STRING into a unicode- and ascii-safe string.
We need unicode so it can be combined with a reversed URL, but it has to be
ascii to go in a Location header. iri_to_uri seems like a good compromise.
"""
qs = request.META['QUERY_STRING']
try:
request.META['QUERY_STRING'] = iri_to_uri(qs)
yield
finally:
request.META['QUERY_STRING'] = qs
class CommonMiddleware(common.CommonMiddleware):
def process_request(self, request):
with safe_query_string(request):
return super(CommonMiddleware, self).process_request(request)

Просмотреть файл

@ -4,8 +4,6 @@ from nose.tools import eq_
def test_no_vary_cookie():
c = test.Client()
# We don't break good usage of Vary.
response = test.Client().get('/')
eq_(response['Vary'], 'Accept-Language')
@ -21,6 +19,6 @@ def test_redirect_with_unicode_get():
def test_trailing_slash_middleware():
response = test.Client().get('/en-US/firefox/about/')
response = test.Client().get(u'/en-US/firefox/about/?xxx=\xc3')
eq_(response.status_code, 301)
assert response['Location'].endswith('/en-US/firefox/about')
assert response['Location'].endswith('/en-US/firefox/about?xxx=%C3%83')

Просмотреть файл

@ -171,7 +171,7 @@ MIDDLEWARE_CLASSES = (
'commonware.middleware.SetRemoteAddrFromForwardedFor',
'commonware.log.ThreadRequestMiddleware',
'django.middleware.common.CommonMiddleware',
'amo.middleware.CommonMiddleware',
'amo.middleware.NoVarySessionMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',