[Zope-Checkins] SVN: Zope/trunk/lib/python/ZServer/ Collector
#2300: delimit *all* headers with CRLF;
accumulated_headers and appendHeader use \n for delimeters and never
get corrected on output
Martijn Pieters
mj at zopatista.com
Tue Mar 27 08:44:28 EDT 2007
Log message for revision 73723:
Collector #2300: delimit *all* headers with CRLF; accumulated_headers and appendHeader use \n for delimeters and never get corrected on output
Changed:
U Zope/trunk/lib/python/ZServer/HTTPResponse.py
U Zope/trunk/lib/python/ZServer/tests/test_responses.py
-=-
Modified: Zope/trunk/lib/python/ZServer/HTTPResponse.py
===================================================================
--- Zope/trunk/lib/python/ZServer/HTTPResponse.py 2007-03-27 12:44:11 UTC (rev 73722)
+++ Zope/trunk/lib/python/ZServer/HTTPResponse.py 2007-03-27 12:44:27 UTC (rev 73723)
@@ -113,8 +113,15 @@
self._chunking=1
else:
self.setHeader('Connection','close')
+
+ headers = headers.items()
+ for line in self.accumulated_headers.splitlines():
+ if line[0] == '\t':
+ headers[-1][1] += '\n' + line
+ continue
+ headers.append(line.split(': ', 1))
- for key, val in headers.items():
+ for key, val in headers:
if key.lower()==key:
# only change non-literal header names
key="%s%s" % (key[:1].upper(), key[1:])
@@ -124,10 +131,13 @@
key="%s-%s%s" % (key[:l],key[l+1:l+2].upper(),key[l+2:])
start=l+1
l=key.find('-',start)
+ val = val.replace('\n\t', '\r\n\t')
append("%s: %s" % (key, val))
if self.cookies:
- headersl=headersl+self._cookie_list()
- headersl[len(headersl):]=[self.accumulated_headers, body]
+ headersl.extend(self._cookie_list())
+
+ append('')
+ append(body)
return "\r\n".join(headersl)
_tempfile=None
@@ -150,6 +160,7 @@
"""
+
if type(data) != type(''):
raise TypeError('Value must be a string')
Modified: Zope/trunk/lib/python/ZServer/tests/test_responses.py
===================================================================
--- Zope/trunk/lib/python/ZServer/tests/test_responses.py 2007-03-27 12:44:11 UTC (rev 73722)
+++ Zope/trunk/lib/python/ZServer/tests/test_responses.py 2007-03-27 12:44:27 UTC (rev 73723)
@@ -56,7 +56,7 @@
one = ZServerHTTPResponse(stdout=DummyChannel())
self.assertRaises(AssertionError,
one.setBody, test_streamiterator())
-
+
class DummyChannel:
def __init__(self):
self.out = StringIO()
@@ -92,8 +92,46 @@
return self.data
raise StopIteration
+class ZServerHTTPResponseTestCase(unittest.TestCase):
+ """Test ZServer HTTPResponse object"""
+
+ def _makeOne(self):
+ return ZServerHTTPResponse()
+
+ def testToString(self):
+ response = self._makeOne()
+ response.headers = {
+ 'content-type': 'text/plain',
+ 'all-lower-case': 'foo',
+ 'Title-Cased': 'bar',
+ 'mixed-CasED': 'spam',
+ 'multilined': 'eggs\n\tham'}
+ response.accumulated_headers = 'foo-bar: bar\n\tbaz\nFoo-bar: monty\n'
+ response.cookies = dict(foo=dict(value='bar'))
+ response.body = 'A body\nwith multiple lines\n'
+
+ result = str(response)
+ headers, body = result.rsplit('\r\n\r\n')
+
+ self.assertEqual(body, response.body)
+
+ self.assertTrue(headers.startswith('HTTP/1.0 200 OK\r\n'))
+
+ # 15 header lines all delimited by \r\n
+ self.assertEqual(
+ ['\n' in line for line in headers.split('\r\n')],
+ 15 * [False])
+
+ self.assertTrue('Multilined: eggs\r\n\tham\r\n' in headers)
+ self.assertTrue('Foo-Bar: bar\r\n\tbaz\r\n' in headers)
+
def test_suite():
- return unittest.makeSuite(ZServerResponseTestCase)
+ suite = unittest.TestSuite()
+ suite.addTests((
+ unittest.makeSuite(ZServerResponseTestCase),
+ unittest.makeSuite(ZServerHTTPResponseTestCase)
+ ))
+ return suite
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")
More information about the Zope-Checkins
mailing list