from django.utils import simplejson import cgi class JSONFilter(object): def __init__(self, app, mime_type='text/x-json'): self.app = app self.mime_type = mime_type def __call__(self, environ, start_response): # Read JSON POST input to jsonfilter.json if matching mime type response = {'status': '200 OK', 'headers': []} def json_start_response(status, headers): response['status'] = status response['headers'].extend(headers) environ['jsonfilter.mime_type'] = self.mime_type if environ.get('REQUEST_METHOD', '') == 'POST': if environ.get('CONTENT_TYPE', '') == self.mime_type: args = [_ for _ in [environ.get('CONTENT_LENGTH')] if _] data = environ['wsgi.input'].read(*map(int, args)) environ['jsonfilter.json'] = simplejson.loads(data) res = simplejson.dumps(self.app(environ, json_start_response)) jsonp = cgi.parse_qs(environ.get('QUERY_STRING', '')).get('jsonp') if jsonp: content_type = 'text/javascript' res = ''.join(jsonp + ['(', res, ')']) elif 'Opera' in environ.get('HTTP_USER_AGENT', ''): # Opera has bunk XMLHttpRequest support for most mime types content_type = 'text/plain' else: content_type = self.mime_type headers = [ ('Content-type', content_type), ('Content-length', len(res)), ] headers.extend(response['headers']) start_response(response['status'], headers) return [res] def factory(app, global_conf, **kw): return JSONFilter(app, **kw)