[Zope3-checkins] SVN: Zope3/trunk/src/zope/server/http/ Handle
headers with duplicate keys as comma seperated lists
Stuart Bishop
stuart at stuartbishop.net
Fri Aug 12 07:39:38 EDT 2005
Log message for revision 37885:
Handle headers with duplicate keys as comma seperated lists
Changed:
U Zope3/trunk/src/zope/server/http/httprequestparser.py
U Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py
U Zope3/trunk/src/zope/server/http/tests/test_httpserver.py
-=-
Modified: Zope3/trunk/src/zope/server/http/httprequestparser.py
===================================================================
--- Zope3/trunk/src/zope/server/http/httprequestparser.py 2005-08-12 10:27:33 UTC (rev 37884)
+++ Zope3/trunk/src/zope/server/http/httprequestparser.py 2005-08-12 11:39:37 UTC (rev 37885)
@@ -126,7 +126,14 @@
key = line[:index]
value = line[index + 1:].strip()
key1 = key.upper().replace('-', '_')
- headers[key1] = value
+ # If a header already exists, we append subsequent values
+ # seperated by a comma. Applications already need to handle
+ # the comma seperated values, as HTTP front ends might do
+ # the concatenation for you (behavior specified in RFC2616).
+ try:
+ headers[key1] += ', %s' % value
+ except KeyError:
+ headers[key1] = value
# else there's garbage in the headers?
command, uri, version = self.crack_first_line()
@@ -143,7 +150,10 @@
buf = OverflowableBuffer(self.adj.inbuf_overflow)
self.body_rcv = ChunkedReceiver(buf)
if not self.chunked:
- cl = int(headers.get('CONTENT_LENGTH', 0))
+ try:
+ cl = int(headers.get('CONTENT_LENGTH', 0))
+ except ValueError:
+ cl = 0
self.content_length = cl
if cl > 0:
buf = OverflowableBuffer(self.adj.inbuf_overflow)
Modified: Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py
===================================================================
--- Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py 2005-08-12 10:27:33 UTC (rev 37884)
+++ Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py 2005-08-12 11:39:37 UTC (rev 37885)
@@ -85,7 +85,26 @@
'd=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6')
self.assertEqual(parser.getBodyStream().getvalue(), 'Hello mick')
+ def testDuplicateHeaders(self):
+ # Ensure that headers with the same key get concatenated as per
+ # RFC2616.
+ data = """\
+GET /foobar HTTP/8.4
+x-forwarded-for: 10.11.12.13
+x-forwarded-for: unknown,127.0.0.1
+X-Forwarded_for: 255.255.255.255
+content-length: 7
+Hello.
+"""
+ self.feed(data)
+ self.failUnless(self.parser.completed)
+ self.assertEqual(self.parser.headers, {
+ 'CONTENT_LENGTH': '7',
+ 'X_FORWARDED_FOR':
+ '10.11.12.13, unknown,127.0.0.1, 255.255.255.255',
+ })
+
def test_suite():
loader = unittest.TestLoader()
return loader.loadTestsFromTestCase(Tests)
Modified: Zope3/trunk/src/zope/server/http/tests/test_httpserver.py
===================================================================
--- Zope3/trunk/src/zope/server/http/tests/test_httpserver.py 2005-08-12 10:27:33 UTC (rev 37884)
+++ Zope3/trunk/src/zope/server/http/tests/test_httpserver.py 2005-08-12 11:39:37 UTC (rev 37885)
@@ -129,8 +129,9 @@
if add_headers:
headers.update(add_headers)
headers["Accept"] = "text/plain"
- if body:
- headers["Content-Length"] = str(int(len(body)))
+ # Content-Length header automatically added by HTTPConnection.request
+ #if body:
+ # headers["Content-Length"] = str(int(len(body)))
h.request("GET", "/", body, headers)
response = h.getresponse()
self.failUnlessEqual(int(response.status), 200)
More information about the Zope3-Checkins
mailing list