1 # Copyright (C) 2015 Ipsilon project Contributors, for license see COPYING
7 def require_content_type(required=None, absent_ok=True, debug=False):
8 '''CherryPy Tool that validates request Content-Type.
10 This is a CherryPy Tool that checks the Content-Type in a request and
11 raises HTTP Error 415 "Unsupported Media Type" if it does not match.
13 The tool accepts a glob style pattern or list of patterns (see fnmatch)
14 and verifies the Content-Type in the request matches at least one of
15 the patterns, if not a HTTP Error 415 "Unsupported Media Type" is raised.
17 If absent_ok is False and if the request does not contain a
18 Content-Type header a HTTP Error 415 "Unsupported Media Type" is
21 The tool may be deployed use any of the standard methods for
22 invoking CherryPy tools, for example as a decorator:
24 @cherrypy.tools.require_content_type(required='text/xml')
25 def POST(self, *args, **kwargs):
28 :param required: May be a single string or a list of strings. Each
29 string is interpreted as a glob style pattern (see fnmatch).
30 The Content-Type must match at least one pattern.
32 :param absent_ok: Boolean specifying if the Content-Type header
33 must be present or if it is OK to be absent.
39 if isinstance(required, basestring):
42 content_type = cherrypy.request.body.content_type.value
46 for pattern in required:
47 if fnmatch.fnmatch(content_type, pattern):
55 cherrypy.log('require_content_type: required=%s, absent_ok=%s '
56 'content_type=%s match=%s pattern=%s' %
57 required, absent_ok, content_type, match, pattern)
60 acceptable = ', '.join(['"%s"' % x for x in required])
62 content_type = '"%s"' % content_type
64 content_type = 'not specified'
65 message = ('Content-Type must match one of following patterns [%s], '
66 'but the Content-Type was %s' %
67 (acceptable, content_type))
68 raise cherrypy.HTTPError(415, message=message)