[Zope-Checkins] SVN: Zope/branches/2.10/ Launchpad #267834: proper separation of HTTP header fields
Laurence Rowe
l at lrowe.co.uk
Sat Apr 25 20:07:42 EDT 2009
Log message for revision 99500:
Launchpad #267834: proper separation of HTTP header fields
using CRLF as requested by RFC 2616. (merged 90980, 92625)
Changed:
U Zope/branches/2.10/doc/CHANGES.txt
U Zope/branches/2.10/lib/python/OFS/tests/testRanges.py
U Zope/branches/2.10/lib/python/Testing/ZopeTestCase/functional.py
U Zope/branches/2.10/lib/python/Testing/tests/test_makerequest.py
U Zope/branches/2.10/lib/python/ZPublisher/HTTPResponse.py
U Zope/branches/2.10/lib/python/ZPublisher/tests/testHTTPResponse.py
-=-
Modified: Zope/branches/2.10/doc/CHANGES.txt
===================================================================
--- Zope/branches/2.10/doc/CHANGES.txt 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/doc/CHANGES.txt 2009-04-26 00:07:42 UTC (rev 99500)
@@ -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.10/lib/python/OFS/tests/testRanges.py
===================================================================
--- Zope/branches/2.10/lib/python/OFS/tests/testRanges.py 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/lib/python/OFS/tests/testRanges.py 2009-04-26 00:07:42 UTC (rev 99500)
@@ -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.10/lib/python/Testing/ZopeTestCase/functional.py
===================================================================
--- Zope/branches/2.10/lib/python/Testing/ZopeTestCase/functional.py 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/lib/python/Testing/ZopeTestCase/functional.py 2009-04-26 00:07:42 UTC (rev 99500)
@@ -106,7 +106,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.10/lib/python/Testing/tests/test_makerequest.py
===================================================================
--- Zope/branches/2.10/lib/python/Testing/tests/test_makerequest.py 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/lib/python/Testing/tests/test_makerequest.py 2009-04-26 00:07:42 UTC (rev 99500)
@@ -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.10/lib/python/ZPublisher/HTTPResponse.py
===================================================================
--- Zope/branches/2.10/lib/python/ZPublisher/HTTPResponse.py 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/lib/python/ZPublisher/HTTPResponse.py 2009-04-26 00:07:42 UTC (rev 99500)
@@ -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
@@ -471,21 +472,20 @@
# Encode the Unicode data as requested
- if self.headers.has_key('content-type'):
- match = charset_re.match(self.headers['content-type'])
+ ct = self.headers.get('content-type')
+ if ct:
+ match = charset_re.match(ct)
if match:
encoding = match.group(1)
body = body.encode(encoding)
body = fix_xml_preamble(body, encoding)
return body
else:
-
- ct = self.headers['content-type']
if ct.startswith('text/') or ct.startswith('application/'):
self.headers['content-type'] = '%s; charset=%s' % (ct, default_encoding)
# Use the default character encoding
- body = body.encode(default_encoding,'replace')
+ body = body.encode(default_encoding, 'replace')
body = fix_xml_preamble(body, default_encoding)
return body
@@ -593,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()
@@ -895,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.10/lib/python/ZPublisher/tests/testHTTPResponse.py
===================================================================
--- Zope/branches/2.10/lib/python/ZPublisher/tests/testHTTPResponse.py 2009-04-25 23:45:05 UTC (rev 99499)
+++ Zope/branches/2.10/lib/python/ZPublisher/tests/testHTTPResponse.py 2009-04-26 00:07:42 UTC (rev 99500)
@@ -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 Zope-Checkins
mailing list