[Checkins] SVN: zope.publisher/trunk/src/zope/publisher/ Fix for https://bugs.launchpad.net/zope3/+bug/98337
Albertas Agejevas
alga at pov.lt
Fri Jul 3 12:02:00 EDT 2009
Log message for revision 101467:
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/trunk/src/zope/publisher/http.py
U zope.publisher/trunk/src/zope/publisher/tests/test_http.py
-=-
Modified: zope.publisher/trunk/src/zope/publisher/http.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/http.py 2009-07-03 16:00:51 UTC (rev 101466)
+++ zope.publisher/trunk/src/zope/publisher/http.py 2009-07-03 16:02:00 UTC (rev 101467)
@@ -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/trunk/src/zope/publisher/tests/test_http.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_http.py 2009-07-03 16:00:51 UTC (rev 101466)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_http.py 2009-07-03 16:02:00 UTC (rev 101467)
@@ -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 import NotFound
@@ -321,7 +322,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
@@ -590,7 +590,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