[Checkins] SVN: zope.publisher/branches/3.4/ Backport r101467 from trunk.
Adam Groszer
agroszer at gmail.com
Tue Apr 6 03:23:32 EDT 2010
Log message for revision 110559:
Backport r101467 from trunk.
Fix for https://bugs.launchpad.net/zope3/+bug/98337
Previously, when the Accept-Charset specified a charset that could not encode
the result, a system error appeared, now we fall back to UTF-8, as per
RFC 2616 section 10.4.7.
Changed:
U zope.publisher/branches/3.4/CHANGES.txt
U zope.publisher/branches/3.4/src/zope/publisher/http.py
U zope.publisher/branches/3.4/src/zope/publisher/tests/test_http.py
-=-
Modified: zope.publisher/branches/3.4/CHANGES.txt
===================================================================
--- zope.publisher/branches/3.4/CHANGES.txt 2010-04-06 07:21:36 UTC (rev 110558)
+++ zope.publisher/branches/3.4/CHANGES.txt 2010-04-06 07:23:32 UTC (rev 110559)
@@ -6,7 +6,14 @@
* Removed ``finally``-clause from test to keep Python2.4 happy.
+* Backport r101467 from trunk.
+ Fix for https://bugs.launchpad.net/zope3/+bug/98337
+
+ Previously, when the Accept-Charset specified a charset that could not encode
+ the result, a system error appeared, now we fall back to UTF-8, as per
+ RFC 2616 section 10.4.7.
+
3.4.9 (2009-07-13)
------------------
@@ -95,9 +102,9 @@
3.4.0b1 (2007-07-05)
--------------------
-* Fix caching issue. The input stream never got cached in a temp file
- because of a wrong content-length header lookup. Added CONTENT_LENGTH
- header check in addition to the previous used HTTP_CONTENT_LENGTH. The
+* Fix caching issue. The input stream never got cached in a temp file
+ because of a wrong content-length header lookup. Added CONTENT_LENGTH
+ header check in addition to the previous used HTTP_CONTENT_LENGTH. The
HTTP\_ prefix is sometimes added by some CGI proxies, but CONTENT_LENGTH
is the right header info for the size.
Modified: zope.publisher/branches/3.4/src/zope/publisher/http.py
===================================================================
--- zope.publisher/branches/3.4/src/zope/publisher/http.py 2010-04-06 07:21:36 UTC (rev 110558)
+++ zope.publisher/branches/3.4/src/zope/publisher/http.py 2010-04-06 07:23:32 UTC (rev 110559)
@@ -814,11 +814,20 @@
if 'charset' in params:
encoding = params['charset']
- else:
- content_type += ';charset=%s' %encoding
- body = body.encode(encoding)
+ try:
+ body = body.encode(encoding)
+ except UnicodeEncodeError:
+ # RFC 2616 section 10.4.7 allows us to return an
+ # unacceptable encoding instead of 406 Not Acceptable
+ # response.
+ encoding = 'utf-8'
+ body = body.encode(encoding)
+ params['charset'] = encoding
+ content_type = "%s/%s;" % (major, minor)
+ content_type += ";".join(k + "=" + v for k, v in params.items())
+
if content_type:
headers = [('content-type', content_type),
('content-length', str(len(body)))]
@@ -827,7 +836,6 @@
return body, headers
-
def handleException(self, exc_info):
"""
Calls self.setBody() with an error response.
Modified: zope.publisher/branches/3.4/src/zope/publisher/tests/test_http.py
===================================================================
--- zope.publisher/branches/3.4/src/zope/publisher/tests/test_http.py 2010-04-06 07:21:36 UTC (rev 110558)
+++ zope.publisher/branches/3.4/src/zope/publisher/tests/test_http.py 2010-04-06 07:23:32 UTC (rev 110559)
@@ -24,6 +24,7 @@
import zope.event
import zope.testing.cleanup
+from zope.component import provideAdapter
from zope.testing import doctest
from zope.i18n.interfaces.locales import ILocale
from zope.interface.verify import verifyObject
@@ -31,7 +32,7 @@
from zope.interface import implements
from zope.publisher.interfaces.logginginfo import ILoggingInfo
from zope.publisher.http import HTTPRequest, HTTPResponse
-from zope.publisher.http import HTTPInputStream, DirectResult
+from zope.publisher.http import HTTPInputStream, DirectResult, HTTPCharsets
from zope.publisher.publish import publish
from zope.publisher.base import DefaultPublication
from zope.publisher.interfaces.http import IHTTPRequest, IHTTPResponse
@@ -297,7 +298,6 @@
eq = self.assertEqual
unless = self.failUnless
- from zope.component import provideAdapter
from zope.publisher.browser import BrowserLanguages
from zope.publisher.interfaces.http import IHTTPRequest
from zope.i18n.interfaces import IUserPreferredLanguages
@@ -565,7 +565,24 @@
request = self._createRequest({'PATH_INFO': '/test '})
self.assertEqual(['test '], request.getTraversalStack())
+ def test_unacceptable_charset(self):
+ # Regression test for https://bugs.launchpad.net/zope3/+bug/98337
+ request = self._createRequest({'HTTP_ACCEPT_CHARSET': 'ISO-8859-1'})
+ result = u"Latin a with ogonek\u0105 Cyrillic ya \u044f"
+ provideAdapter(HTTPCharsets)
+ request.response.setHeader('Content-Type', 'text/plain')
+ # Instead of failing with HTTP code 406 we ignore the
+ # Accept-Charset header and return a response in UTF-8.
+ request.response.setResult(result)
+
+ body = request.response.consumeBody()
+ self.assertEquals(request.response.getStatus(), 200)
+ self.assertEquals(request.response.getHeader('Content-Type'),
+ 'text/plain;charset=utf-8')
+ self.assertEquals(body,
+ 'Latin a with ogonek\xc4\x85 Cyrillic ya \xd1\x8f')
+
class ConcreteHTTPTests(HTTPTests):
"""Tests that we don't have to worry about subclasses inheriting and
breaking.
More information about the checkins
mailing list