Commit 2f653107 authored by Ralf Schmitt's avatar Ralf Schmitt Committed by Denis Bilenko

fix handling of multiline HTTP headers in pywsgi

this is issue https://github.com/SiteSupport/gevent/issues/116

the mimetools Message class isn't of much help here, but replacing it
probably will do more harm than good. so, we parse multiline headers
on our own.

The
,----
| if 'bytearray' in __builtins__.__dict__:
`----
fails when running under py.test, so I replaced that too.
parent 266ab4c3
......@@ -523,6 +523,23 @@ class WSGIHandler(object):
self.start_response(_INTERNAL_ERROR_STATUS, _INTERNAL_ERROR_HEADERS)
self.write(_INTERNAL_ERROR_BODY)
def _headers(self):
key = None
value = None
for header in self.headers.headers:
if key is not None and header[:1] in " \t":
value += header
continue
if key not in (None, 'CONTENT_TYPE', 'CONTENT_LENGTH'):
yield 'HTTP_' + key, value.strip()
key, value = header.split(':', 1)
key = key.replace('-', '_').upper()
if key not in (None, 'CONTENT_TYPE', 'CONTENT_LENGTH'):
yield 'HTTP_' + key, value.strip()
def get_environ(self):
env = self.server.get_environ()
env['REQUEST_METHOD'] = self.command
......@@ -548,19 +565,14 @@ class WSGIHandler(object):
env['REMOTE_ADDR'] = str(client_address[0])
env['REMOTE_PORT'] = str(client_address[1])
for header in self.headers.headers:
key, value = header.split(':', 1)
key = key.replace('-', '_').upper()
if key not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
value = value.strip()
key = 'HTTP_' + key
if key in env:
if 'COOKIE' in key:
env[key] += '; ' + value
else:
env[key] += ',' + value
for key, value in self._headers():
if key in env:
if 'COOKIE' in key:
env[key] += '; ' + value
else:
env[key] = value
env[key] += ',' + value
else:
env[key] = value
if env.get('HTTP_EXPECT') == '100-continue':
socket = self.socket
......
......@@ -371,7 +371,7 @@ class TestYield(CommonTests):
yield "not found"
if 'bytearray' in __builtins__.__dict__:
if sys.version_info[:2] >= (2, 6):
class TestBytearray(CommonTests):
......@@ -388,6 +388,27 @@ if 'bytearray' in __builtins__.__dict__:
return [bytearray("not found")]
class MultiLineHeader(TestCase):
@staticmethod
def application(env, start_response):
assert "test.submit" in env["CONTENT_TYPE"]
start_response('200 OK', [('Content-Type', 'text/plain')])
return ["ok"]
def test_multiline_116(self):
"""https://github.com/SiteSupport/gevent/issues/116"""
request = '\r\n'.join((
'POST / HTTP/1.0',
'Host: localhost',
'Content-Type: multipart/related; boundary="====XXXX====";',
' type="text/xml";start="test.submit"',
'Content-Length: 0',
'', ''))
fd = self.makefile()
fd.write(request)
read_http(fd, version='1.0')
class TestGetArg(TestCase):
@staticmethod
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment