Nevow error with unicode localization in appserver.py
Below suggested patches to omit broken output, if unicode is returned instead of string. Problem occurred during localization with gettext, see this sample code: ------------------------------------------------------------------- import gettext from twisted.internet import reactor from twisted.protocols import http from nevow import inevow, rend, loaders, tags, appserver, static, guard class Index(rend.Page): addSlash = True child_css = static.File('static/css') child_img = static.File('static/img') docFactory = loaders.xmlfile('static/index.html') def renderHTTP(self, ctx): request = inevow.IRequest(ctx) # Dynamic LOCALIZATION =============================================== # inspired by http://www.ospace.net/index.en.html language = request.getHeader('accept-language').split(',')[0][:2] try: tran = gettext.translation('PROJECT', 'static/locale', languages = [language]) except IOError: print 'Cannot find catalog for "', language, '", installing null translations' tran = gettext.NullTranslations() tran.install(unicode = 1) # ==================================================================== # got from: nevow/examples/http_auth.py username, password = request.getUser(), request.getPassword() if (username, password) == ('', ''): request.setHeader('WWW-Authenticate', 'Basic realm="Whatever"') request.setResponseCode(http.UNAUTHORIZED) return _("Authentication required.") # THIS RETURN UNICODE ## They provided a username and password, so let's let them in! hurray self.data_username, self.data_password = username, password return rend.Page.renderHTTP(self, ctx) site = appserver.NevowSite(Index()) reactor.listenTCP(8080, site) reactor.run() ------------------------------------------------------------------- Paul Reznicek Necessary patch: =================================================================== --- nevow/appserver.py (Revision 1126) +++ nevow/appserver.py (local) @@ -167,8 +167,8 @@ self.deferred.callback("") def _cbFinishRender(self, html, ctx): - if isinstance(html, str): - self.write(html) + if isinstance(html, basestring): + self.write(html.encode('utf8')) server.Request.finish(self) elif html is errorMarker: ## Error webpage has already been rendered and finish called I believe, the wsgi.py can have similar problem: =================================================================== --- nevow/wsgi.py (Revision 1126) +++ nevow/wsgi.py (local) @@ -84,8 +84,8 @@ p = rend.FourOhFour() result = p.renderHTTP(pctx) - if isinstance(result, str): - request.write(result) + if isinstance(result, basestring): + request.write(result.encode('utf8')) else: ## Exhaust the generator list(result)
On Jan 27, 2005, at 5:49 PM, Paul Reznicek wrote:
Below suggested patches to omit broken output, if unicode is returned instead of string. Problem occurred during localization with gettext, see this sample code:
Necessary patch: =================================================================== --- appserver.py (Revision 1126) +++ appserver.py (local) @@ -170,6 +170,9 @@ if isinstance(html, str): self.write(html) server.Request.finish(self) + elif isinstance(html, unicode): + self.write(html.encode('utf8')) + server.Request.finish(self) elif html is errorMarker: ## Error webpage has already been rendered and finish called pass
No. HTTP talks bytes, not characters. If you use the nevow rendering stuff, you get automatic encoding of characters into bytes via the UTF-8 encoding, but if you're going to override renderHTTP and return your own data, it should be a byte string. appserver is really part of the HTTP server, not nevow (even though it is in the nevow package at the moment), and thus ought not know or care anything about what kind of data you are sending. It could be html in UTF-8, html in ISO8859-1, jpeg images, anything. James
OK - thanks for explanation, you're right! Paul James Y Knight wrote:
No. HTTP talks bytes, not characters. If you use the nevow rendering stuff, you get automatic encoding of characters into bytes via the UTF-8 encoding, but if you're going to override renderHTTP and return your own data, it should be a byte string.
appserver is really part of the HTTP server, not nevow (even though it is in the nevow package at the moment), and thus ought not know or care anything about what kind of data you are sending. It could be html in UTF-8, html in ISO8859-1, jpeg images, anything.
James
participants (2)
-
James Y Knight
-
Paul Reznicek