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 parsing #1412

Merged
merged 1 commit into from
Jan 30, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions liberapay/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import signal
import string
from threading import Timer
import urllib
from urllib.parse import quote as urlquote, quote_plus as urlquote_plus, urlencode

import aspen
import aspen.http.mapping
Expand All @@ -28,7 +28,7 @@
from liberapay.models.repository import refetch_repos
from liberapay.security import authentication, csrf, set_default_security_headers
from liberapay.utils import (
b64decode_s, b64encode_s, erase_cookie, http_caching, set_cookie, urlquote,
b64decode_s, b64encode_s, erase_cookie, http_caching, set_cookie,
)
from liberapay.utils.emails import handle_email_bounces
from liberapay.utils.state_chain import (
Expand Down Expand Up @@ -225,7 +225,7 @@ def _Querystring_derive(self, **kw):
new_qs = aspen.http.mapping.Mapping(self)
for k, v in kw.items():
new_qs[k] = v
return '?' + urllib.parse.urlencode(new_qs, doseq=True)
return '?' + urlencode(new_qs, doseq=True)
aspen.http.request.Querystring.derive = _Querystring_derive

if hasattr(pando.http.request.Request, 'source'):
Expand Down Expand Up @@ -368,3 +368,27 @@ def _decode_body(self):
body = self.body
return body.decode('utf8') if isinstance(body, bytes) else body
pando.Response.text = property(_decode_body)

# The monkey-patch below is only for Pando 0.45, it should be removed after that
def make_franken_uri(path, qs):
if path:
try:
if type(path) is bytes:
path.decode('ascii')
else:
path = path.encode('ascii')
except UnicodeError:
path = urlquote(path, '%/').encode('ascii')

if qs:
try:
if type(qs) is bytes:
qs.decode('ascii')
else:
qs = qs.encode('ascii')
except UnicodeError:
qs = urlquote_plus(qs, '%=&').encode('ascii')
qs = b'?' + qs

return path + qs
pando.http.request.make_franken_uri = make_franken_uri
5 changes: 0 additions & 5 deletions tests/py/test_state_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from pando.http.request import Request
from pando.http.response import Response
import pytest

from liberapay.security import csrf
from liberapay.testing import Harness
Expand Down Expand Up @@ -201,9 +200,7 @@ def test_quoted_unicode_path_is_okay(self):
r = self.client.GET('', PATH_INFO='/about/%C3%A9', raise_immediately=False)
assert r.code == 404, r.text

@pytest.mark.xfail
def test_unquoted_unicode_path_is_okay(self):
# These fail because of bugs in Pando
r = self.client.GET('/about/é'.encode('utf8'), raise_immediately=False)
assert r.code == 404, r.text
r = self.client.GET('', PATH_INFO='/about/é', raise_immediately=False)
Expand All @@ -215,9 +212,7 @@ def test_quoted_unicode_querystring_is_okay(self):
r = self.client.GET('/', QUERY_STRING='%C3%A9=%C3%A9', raise_immediately=False)
assert r.code == 200, r.text

@pytest.mark.xfail
def test_unquoted_unicode_querystring_is_okay(self):
# These fail because of bugs in Pando
r = self.client.GET('/', QUERY_STRING='é=é'.encode('utf8'), raise_immediately=False)
assert r.code == 200, r.text
r = self.client.GET('/', QUERY_STRING='é=é', raise_immediately=False)
Expand Down