[Zope2] Multiline response headers causing problems for proxies.
Laurence Rowe <[email protected]>
| Newsgroups | gmane.comp.web.zope.devel |
|---|---|
| Message-ID | <[email protected]> |
When using response.appendHeader, Zope appends the new value following
an ",\r\n\t" which splits the header over multiple lines. While this
behaviour is standards compliant, it causes problems for both Varnish
[1] and Nginx [2] which may then mangle the header value.
In fact the HTTP 1.0 spec notes that splitting over multiple lines in
not recommended [3], though the HTTP 1.1 spec does not mention this
explicitly, though it does say [4]:
"Applications ought to follow "common form", where one is known or
indicated, when generating HTTP constructs, since there might exist
some implementations that fail to accept anything"
Are there any objections to me applying the attached patch to Zope
2.13 and trunk?
Laurence
[1] http://www.varnish-cache.org/trac/ticket/905
[2] http://nginx.org/pipermail/nginx-devel/2011-April/000859.html
[3] http://tools.ietf.org/html/rfc1945#section-4.2
[4] http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
_______________________________________________
Zope-Dev maillist - [email protected]
https://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
https://mail.zope.org/mailman/listinfo/zope-announce
https://mail.zope.org/mailman/listinfo/zope )
appendHeader.patch
(application/octet-stream, 1.8 KB)
Index: src/ZPublisher/HTTPResponse.py
===================================================================
--- src/ZPublisher/HTTPResponse.py (revision 121442)
+++ src/ZPublisher/HTTPResponse.py (working copy)
@@ -338,7 +338,7 @@
name = literal and name or key
self.headers[name] = value
- def appendHeader(self, name, value, delimiter=","):
+ def appendHeader(self, name, value, delimiter=", "):
""" Append a value to an HTTP return header.
Set an HTTP return header "name" with value "value",
@@ -353,7 +353,7 @@
headers = self.headers
if headers.has_key(name):
h = headers[name]
- h = "%s%s\r\n\t%s" % (h, delimiter, value)
+ h = "%s%s%s" % (h, delimiter, value)
else:
h = value
self.setHeader(name,h, scrubbed=True)
Index: src/ZPublisher/tests/testHTTPResponse.py
===================================================================
--- src/ZPublisher/tests/testHTTPResponse.py (revision 121442)
+++ src/ZPublisher/tests/testHTTPResponse.py (working copy)
@@ -445,13 +445,13 @@
response = self._makeOne()
response.setHeader('foo', 'bar')
response.appendHeader('foo', 'foo')
- self.assertEqual(response.headers.get('foo'), 'bar,\r\n\tfoo')
+ self.assertEqual(response.headers.get('foo'), 'bar, foo')
def test_appendHeader_w_existing_case_insenstative(self):
response = self._makeOne()
response.setHeader('xxx', 'bar')
response.appendHeader('XXX', 'foo')
- self.assertEqual(response.headers.get('xxx'), 'bar,\r\n\tfoo')
+ self.assertEqual(response.headers.get('xxx'), 'bar, foo')
def test_appendHeader_drops_CRLF(self):
# RFC2616 disallows CRLF in a header value.