diff options
author | Ryan Petrello <lists@ryanpetrello.com> | 2012-11-02 17:25:34 -0400 |
---|---|---|
committer | Ryan Petrello <lists@ryanpetrello.com> | 2012-11-03 07:17:11 -0400 |
commit | eccc1eff14b39c9758ea3865d62865890130cc1c (patch) | |
tree | 1ffb0ea9a19036fe1315e58e87a9de605e75ef35 /pecan/core.py | |
parent | d8e53a2c8318d97952e6b13a19d2f5c44cbbb55a (diff) | |
download | pecan-eccc1eff14b39c9758ea3865d62865890130cc1c.tar.gz |
Add support for content type detection via Accept headers.
Diffstat (limited to 'pecan/core.py')
-rw-r--r-- | pecan/core.py | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/pecan/core.py b/pecan/core.py index 1ff1663..20576e1 100644 --- a/pecan/core.py +++ b/pecan/core.py @@ -3,7 +3,7 @@ from routing import lookup_controller, NonCanonicalPath from util import _cfg, encode_if_needed from middleware.recursive import ForwardRequestException -from webob import Request, Response, exc +from webob import Request, Response, exc, acceptparse from threading import local from itertools import chain from mimetypes import guess_type, add_type @@ -367,6 +367,7 @@ class Pecan(object): # by the file extension on the URI path = request.pecan['routing_path'] + # attempt to guess the content type based on the file extension if not request.pecan['content_type'] and '.' in path.split('/')[-1]: path, extension = splitext(path) request.pecan['extension'] = extension @@ -392,10 +393,35 @@ class Pecan(object): # if unsure ask the controller for the default content type if not request.pecan['content_type']: - request.pecan['content_type'] = cfg.get( - 'content_type', - 'text/html' - ) + # attempt to find a best match based on accept headers (if they + # exist) + if 'Accept' in request.headers: + best_default = acceptparse.MIMEAccept( + request.headers['Accept'] + ).best_match( + cfg.get('content_types', {}).keys() + ) + + if best_default is None: + import warnings + msg = "Controller '%s' defined does not support " + \ + "content_type '%s'. Supported type(s): %s" + warnings.warn( + msg % ( + controller.__name__, + request.pecan['content_type'], + cfg.get('content_types', {}).keys() + ), + RuntimeWarning + ) + raise exc.HTTPNotFound + + request.pecan['content_type'] = best_default + else: + request.pecan['content_type'] = cfg.get( + 'content_type', + 'text/html' + ) elif cfg.get('content_type') is not None and \ request.pecan['content_type'] not in \ cfg.get('content_types', {}): |