summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert JW Regeer <bertjw@regeer.org>2016-04-12 18:52:25 -0600
committerBert JW Regeer <bertjw@regeer.org>2016-04-12 20:21:43 -0600
commitcb67e01c07be14994229f584d8b6b6edcf84da78 (patch)
tree8d64f31bebdda8a2773bb02a1d02eb64d09fcc71
parentefaf7300c9c3ef2a795aae7f724bf5b02e96cd75 (diff)
downloadpyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.tar.gz
pyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.tar.bz2
pyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.zip
Using WebOb's acceptparse find best mimetype to use
We default to text/plain.
-rw-r--r--pyramid/httpexceptions.py51
1 files changed, 44 insertions, 7 deletions
diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py
index 8bf9a0a72..ef1e5c144 100644
--- a/pyramid/httpexceptions.py
+++ b/pyramid/httpexceptions.py
@@ -123,12 +123,14 @@ The subclasses of :class:`~_HTTPMove`
field. Reflecting this, these subclasses have one additional keyword argument:
``location``, which indicates the location to which to redirect.
"""
+import json
from string import Template
from zope.interface import implementer
from webob import html_escape as _html_escape
+from webob.acceptparse import Accept
from pyramid.compat import (
class_types,
@@ -214,7 +216,7 @@ ${body}''')
empty_body = False
def __init__(self, detail=None, headers=None, comment=None,
- body_template=None, **kw):
+ body_template=None, json_formatter=None, **kw):
status = '%s %s' % (self.code, self.title)
Response.__init__(self, status=status, **kw)
Exception.__init__(self, detail)
@@ -225,6 +227,8 @@ ${body}''')
if body_template is not None:
self.body_template = body_template
self.body_template_obj = Template(body_template)
+ if json_formatter is not None:
+ self._json_formatter = json_formatter
if self.empty_body:
del self.content_type
@@ -233,31 +237,64 @@ ${body}''')
def __str__(self):
return self.detail or self.explanation
+ def _json_formatter(self, status, body, title, environ):
+ return {'message': body,
+ 'code': status,
+ 'title': self.title}
+
def prepare(self, environ):
if not self.body and not self.empty_body:
html_comment = ''
comment = self.comment or ''
- accept = environ.get('HTTP_ACCEPT', '')
- if accept and 'html' in accept or '*/*' in accept:
+ accept_value = environ.get('HTTP_ACCEPT', '')
+ accept = Accept(accept_value)
+ match = accept.best_match(
+ ['application/json',
+ 'text/html',
+ 'text/plain'], default_match='text/plain')
+
+ if match == 'text/html':
self.content_type = 'text/html'
+ self.charset = 'utf-8'
escape = _html_escape
page_template = self.html_template_obj
br = '<br/>'
if comment:
html_comment = '<!-- %s -->' % escape(comment)
+ elif match == 'application/json':
+ self.content_type = 'application/json'
+ self.charset = ''
+ escape = _no_escape
+ br = '\n'
+ if comment:
+ html_comment = escape(comment)
+
+ class JsonPageTemplate(object):
+ def __init__(self, excobj):
+ self.excobj = excobj
+
+ def substitute(self, status, body):
+ jsonbody = self.excobj._json_formatter(
+ status=status,
+ body=body, title=self.excobj.title,
+ environ=environ)
+ return json.dumps(jsonbody)
+
+ page_template = JsonPageTemplate(self)
else:
self.content_type = 'text/plain'
+ self.charset = 'utf-8'
escape = _no_escape
page_template = self.plain_template_obj
br = '\n'
if comment:
html_comment = escape(comment)
args = {
- 'br':br,
+ 'br': br,
'explanation': escape(self.explanation),
'detail': escape(self.detail or ''),
'comment': escape(comment),
- 'html_comment':html_comment,
+ 'html_comment': html_comment,
}
body_tmpl = self.body_template_obj
if HTTPException.body_template_obj is not body_tmpl:
@@ -1001,8 +1038,8 @@ class HTTPInternalServerError(HTTPServerError):
code = 500
title = 'Internal Server Error'
explanation = (
- 'The server has either erred or is incapable of performing '
- 'the requested operation.')
+ 'The server has either erred or is incapable of performing '
+ 'the requested operation.')
class HTTPNotImplemented(HTTPServerError):
"""