diff --git a/klein/resource.py b/klein/resource.py index 4e0fae90f..151ee90b1 100644 --- a/klein/resource.py +++ b/klein/resource.py @@ -8,7 +8,17 @@ from klein.interfaces import IKleinRequest -__all__ = ["KleinResource"] +__all__ = ["KleinResource", "ensure_utf8_bytes"] + + +def ensure_utf8_bytes(v): + """ + Coerces a value which is either a C{unicode} or C{str} to a C{str}. + If ``v`` is a C{unicode} object it is encoded as utf-8. + """ + if isinstance(v, unicode): + v = v.encode("utf-8") + return v class KleinResource(Resource): @@ -63,9 +73,9 @@ def render(self, request): resp = he.get_response({}) for header, value in resp.headers: - request.setHeader(header, value) + request.setHeader(ensure_utf8_bytes(header), ensure_utf8_bytes(value)) - return he.get_body({}) + return ensure_utf8_bytes(he.get_body({})) # Try pretty hard to fix up prepath and postpath. segment_count = self._app.endpoints[endpoint].segment_count diff --git a/klein/test_resource.py b/klein/test_resource.py index 049f0114d..d8a17bb47 100644 --- a/klein/test_resource.py +++ b/klein/test_resource.py @@ -5,7 +5,7 @@ from twisted.trial import unittest from klein import Klein -from klein.resource import KleinResource +from klein.resource import KleinResource, ensure_utf8_bytes from klein.interfaces import IKleinRequest from twisted.internet.defer import succeed, Deferred @@ -653,3 +653,8 @@ def _cb(result): d.addCallback(_cb) return d + + def test_ensure_utf8_bytes(self): + self.assertEqual(ensure_utf8_bytes(u"abc"), "abc") + self.assertEqual(ensure_utf8_bytes(u"\u2202"), "\xe2\x88\x82") + self.assertEqual(ensure_utf8_bytes("\xe2\x88\x82"), "\xe2\x88\x82")