[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