From 68368586a7f84077fabda076cab5189f116377a0 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Mon, 11 Mar 2013 15:06:00 -0400 Subject: [PATCH] add support for application/json as Unicode text --- src/zope/publisher/http.py | 18 ++++++++++++------ src/zope/publisher/tests/test_http.py | 5 +++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/zope/publisher/http.py b/src/zope/publisher/http.py index ae087cf2..656a99d3 100644 --- a/src/zope/publisher/http.py +++ b/src/zope/publisher/http.py @@ -49,7 +49,8 @@ # not just text/* but RFC 3023 and */*+xml import re -unicode_mimetypes_re = re.compile(r"^text\/.*$|^.*\/xml.*$|^.*\+xml$") +unicode_mimetypes_re = re.compile( + r"^text\/.*$|^.*\/xml.*$|^.*\+xml$|^application/json$") eventlog = logging.getLogger('eventlog') @@ -799,8 +800,8 @@ def _implicitResult(self, body): if isinstance(body, unicode): if not unicode_mimetypes_re.match(content_type): raise ValueError( - 'Unicode results must have a text, RFC 3023, or ' - '+xml content type.') + 'Unicode results must have a text, RFC 3023, RFC 4627,' + ' or +xml content type.') major, minor, params = zope.contenttype.parse.parse(content_type) @@ -816,9 +817,14 @@ def _implicitResult(self, body): 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 (major, minor) != ('application', 'json'): + # The RFC says this is UTF-8, and the type has no params. + params['charset'] = encoding + content_type = "%s/%s" % (major, minor) + if params: + content_type += ";" + content_type += ";".join(k + "=" + v + for k, v in params.items()) if content_type: headers = [('content-type', content_type), diff --git a/src/zope/publisher/tests/test_http.py b/src/zope/publisher/tests/test_http.py index 29e95604..607e257c 100644 --- a/src/zope/publisher/tests/test_http.py +++ b/src/zope/publisher/tests/test_http.py @@ -831,6 +831,11 @@ def testContentType(self): eq("image/gif", headers["Content-Type"]) eq("test", body) + headers, body = self._getResultFromResponse(u"test", "utf-8", + {"content-type": "application/json"}) + eq("application/json", headers["Content-Type"]) + eq(b"test", body) + def _getCookieFromResponse(self, cookies): # Shove the cookies through request, parse the Set-Cookie header # and spit out a list of headers for examination