[Checkins] SVN: Zope/branches/2.11/ Launchpad #267834: proper separation of HTTP header fields

Laurence Rowe l at lrowe.co.uk
Sat Apr 25 20:07:59 EDT 2009


Log message for revision 99501:
  Launchpad #267834: proper separation of HTTP header fields    
          using CRLF as requested by RFC 2616. (merged 90980, 92625)

Changed:
  U   Zope/branches/2.11/doc/CHANGES.txt
  U   Zope/branches/2.11/lib/python/OFS/tests/testRanges.py
  U   Zope/branches/2.11/lib/python/Testing/ZopeTestCase/functional.py
  U   Zope/branches/2.11/lib/python/Testing/tests/test_makerequest.py
  U   Zope/branches/2.11/lib/python/ZPublisher/HTTPResponse.py
  U   Zope/branches/2.11/lib/python/ZPublisher/tests/testHTTPResponse.py

-=-
Modified: Zope/branches/2.11/doc/CHANGES.txt
===================================================================
--- Zope/branches/2.11/doc/CHANGES.txt	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/doc/CHANGES.txt	2009-04-26 00:07:58 UTC (rev 99501)
@@ -27,6 +27,9 @@
 
     Bugs Fixed
 
+      - Launchpad #267834: proper separation of HTTP header fields    
+        using CRLF as requested by RFC 2616. (merged 90980, 92625)
+
       - Launchpad #348223: optimize catalog query by breaking out early from
         loop over indexes if the result set is already empty.
 

Modified: Zope/branches/2.11/lib/python/OFS/tests/testRanges.py
===================================================================
--- Zope/branches/2.11/lib/python/OFS/tests/testRanges.py	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/lib/python/OFS/tests/testRanges.py	2009-04-26 00:07:58 UTC (rev 99501)
@@ -102,7 +102,7 @@
 
         # Chop off any printed headers (only when response.write was used)
         if body:
-            body = string.split(body, '\n\n', 1)[1]
+            body = string.split(body, '\r\n\r\n', 1)[1]
 
         return body + rv
 

Modified: Zope/branches/2.11/lib/python/Testing/ZopeTestCase/functional.py
===================================================================
--- Zope/branches/2.11/lib/python/Testing/ZopeTestCase/functional.py	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/lib/python/Testing/ZopeTestCase/functional.py	2009-04-26 00:07:58 UTC (rev 99501)
@@ -108,7 +108,7 @@
 class ResponseWrapper:
     '''Decorates a response object with additional introspective methods.'''
 
-    _bodyre = re.compile('^$^\n(.*)', re.MULTILINE | re.DOTALL)
+    _bodyre = re.compile('\r\n\r\n(.*)', re.MULTILINE | re.DOTALL)
 
     def __init__(self, response, outstream, path):
         self._response = response

Modified: Zope/branches/2.11/lib/python/Testing/tests/test_makerequest.py
===================================================================
--- Zope/branches/2.11/lib/python/Testing/tests/test_makerequest.py	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/lib/python/Testing/tests/test_makerequest.py	2009-04-26 00:07:58 UTC (rev 99501)
@@ -51,7 +51,7 @@
         item.REQUEST.RESPONSE.write('aaa')
         out.seek(0)
         written = out.read()
-        self.failUnless(written.startswith('Status: 200 OK\n'))
+        self.failUnless(written.startswith('Status: 200 OK\r\n'))
         self.failUnless(written.endswith('\naaa'))
 
     def test_environ(self):

Modified: Zope/branches/2.11/lib/python/ZPublisher/HTTPResponse.py
===================================================================
--- Zope/branches/2.11/lib/python/ZPublisher/HTTPResponse.py	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/lib/python/ZPublisher/HTTPResponse.py	2009-04-26 00:07:58 UTC (rev 99501)
@@ -221,7 +221,7 @@
             # It has already been determined.
             return
 
-        if (isinstance(status, types.ClassType)
+        if (isinstance(status, (type, types.ClassType))
          and issubclass(status, Exception)):
             status = status.__name__
 
@@ -246,17 +246,18 @@
         if lock:
              self._locked_status = 1
 
-    def setHeader(self, name, value, literal=0):
+    def setHeader(self, name, value, literal=0, scrubbed=False):
         '''\
         Sets an HTTP return header "name" with value "value", clearing
         the previous value set for the header, if one exists. If the
         literal flag is true, the case of the header name is preserved,
         otherwise the header name will be lowercased.'''
-        name, value = _scrubHeader(name, value)
+        if not scrubbed:
+            name, value = _scrubHeader(name, value)
         key = name.lower()
         if accumulate_header(key):
             self.accumulated_headers = (
-                "%s%s: %s\n" % (self.accumulated_headers, name, value))
+                "%s%s: %s\r\n" % (self.accumulated_headers, name, value))
             return
         name = literal and name or key
         self.headers[name] = value
@@ -279,7 +280,7 @@
         any previously set headers with the same name.'''
         name, value = _scrubHeader(name, value)
         self.accumulated_headers = (
-            "%s%s: %s\n" % (self.accumulated_headers, name, value))
+            "%s%s: %s\r\n" % (self.accumulated_headers, name, value))
 
     __setitem__ = setHeader
 
@@ -592,10 +593,10 @@
         headers = self.headers
         if headers.has_key(name):
             h = headers[name]
-            h = "%s%s\n\t%s" % (h,delimiter,value)
+            h = "%s%s\r\n\t%s" % (h,delimiter,value)
         else:
             h = value
-        self.setHeader(name,h)
+        self.setHeader(name,h, scrubbed=True)
 
     def isHTML(self, s):
         s = s.lstrip()
@@ -894,7 +895,7 @@
         if self.cookies:
             headersl = headersl+self._cookie_list()
         headersl[len(headersl):] = [self.accumulated_headers, body]
-        return '\n'.join(headersl)
+        return '\r\n'.join(headersl)
 
     def write(self,data):
         """\

Modified: Zope/branches/2.11/lib/python/ZPublisher/tests/testHTTPResponse.py
===================================================================
--- Zope/branches/2.11/lib/python/ZPublisher/tests/testHTTPResponse.py	2009-04-26 00:07:42 UTC (rev 99500)
+++ Zope/branches/2.11/lib/python/ZPublisher/tests/testHTTPResponse.py	2009-04-26 00:07:58 UTC (rev 99501)
@@ -72,10 +72,10 @@
         response = self._makeOne()
         response.setHeader('foo', 'bar')
         response.appendHeader('foo', 'foo')
-        self.assertEqual(response.headers.get('foo'), 'bar,\n\tfoo')
+        self.assertEqual(response.headers.get('foo'), 'bar,\r\n\tfoo')
         response.setHeader('xxx', 'bar')
         response.appendHeader('XXX', 'foo')
-        self.assertEqual(response.headers.get('xxx'), 'bar,\n\tfoo')
+        self.assertEqual(response.headers.get('xxx'), 'bar,\r\n\tfoo')
 
     def test_setHeader(self):
         response = self._makeOne()
@@ -151,7 +151,7 @@
         response.addHeader('Location',
                            'http://www.ietf.org/rfc/\r\nrfc2616.txt')
         self.assertEqual(response.accumulated_headers,
-                         'Location: http://www.ietf.org/rfc/rfc2616.txt\n')
+                         'Location: http://www.ietf.org/rfc/rfc2616.txt\r\n')
 
     def test_appendHeader_drops_CRLF(self):
         # RFC2616 disallows CRLF in a header value.
@@ -176,8 +176,9 @@
         response.setHeader('Set-Cookie',
                        'violation="http://www.ietf.org/rfc/\r\nrfc2616.txt"')
         self.assertEqual(response.accumulated_headers,
-                'Set-Cookie: allowed="OK"\n' +
-                'Set-Cookie: violation="http://www.ietf.org/rfc/rfc2616.txt"\n')
+                'Set-Cookie: allowed="OK"\r\n' +
+                'Set-Cookie: '
+                'violation="http://www.ietf.org/rfc/rfc2616.txt"\r\n')
 
 
 def test_suite():



More information about the Checkins mailing list