summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Burke <tim.burke@gmail.com>2016-08-08 12:46:17 -0700
committerSergey Shepelev <temotor@gmail.com>2016-08-09 00:46:17 +0500
commite61a19b0ae033c6126f6c2fd23a717ca317964e8 (patch)
treefaedce7893eaf1a4c032938f5f94569d7a1d95bf
parentc7e56d6b37d46c55293226c3c909d9fe3cfe70a2 (diff)
downloadeventlet-e61a19b0ae033c6126f6c2fd23a717ca317964e8.tar.gz
wsgi: only skip Content-Type and Content-Length headers (GH-327)
Previously, some HTTP headers would not be transcribed to the WSGI environment provided to applications. This could be happen if either: * the header closely mirrors another CGI variable, such as Request-Method or Path-Info, or * the header closely mirrors a previous header but prefixed with "Http-", such as Http-Foo when a Foo header has already been received. Now, only Content-Type and Content-Length will be skipped, and only because they were previously already added as CONTENT_TYPE and CONTENT_LENGTH keys. https://github.com/eventlet/eventlet/pull/327
-rw-r--r--eventlet/wsgi.py3
-rw-r--r--tests/wsgi_test.py16
2 files changed, 18 insertions, 1 deletions
diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py
index edc5486..6adc613 100644
--- a/eventlet/wsgi.py
+++ b/eventlet/wsgi.py
@@ -604,7 +604,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
env['headers_raw'] = headers_raw = tuple((k, v.strip()) for k, v in headers)
for k, v in headers_raw:
k = k.replace('-', '_').upper()
- if k in env:
+ if k in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
+ # These do not get the HTTP_ prefix and were handled above
continue
envk = 'HTTP_' + k
if envk in env:
diff --git a/tests/wsgi_test.py b/tests/wsgi_test.py
index 48f5836..76f64f0 100644
--- a/tests/wsgi_test.py
+++ b/tests/wsgi_test.py
@@ -1541,6 +1541,22 @@ class TestHttpd(_TestBase):
assert result.status == 'HTTP/1.1 200 OK'
assert result.body == b'Host: localhost\nx-ANY_k: one\nx-ANY_k: two'
+ def test_env_headers(self):
+ def app(environ, start_response):
+ start_response('200 OK', [])
+ return ['{0}: {1}\n'.format(*kv).encode() for kv in sorted(environ.items())
+ if kv[0].startswith('HTTP_')]
+
+ self.spawn_server(site=app)
+ sock = eventlet.connect(self.server_addr)
+ sock.sendall(b'GET / HTTP/1.1\r\nHost: localhost\r\npath-info: foo\r\n'
+ b'x-ANY_k: one\r\nhttp-x-ANY_k: two\r\n\r\n')
+ result = read_http(sock)
+ sock.close()
+ assert result.status == 'HTTP/1.1 200 OK', 'Received status {0!r}'.format(result.status)
+ assert result.body == (b'HTTP_HOST: localhost\nHTTP_HTTP_X_ANY_K: two\n'
+ b'HTTP_PATH_INFO: foo\nHTTP_X_ANY_K: one\n')
+
def read_headers(sock):
fd = sock.makefile('rb')