|
1 from django.utils import simplejson |
|
2 import cgi |
|
3 |
|
4 class JSONFilter(object): |
|
5 def __init__(self, app, mime_type='text/x-json'): |
|
6 self.app = app |
|
7 self.mime_type = mime_type |
|
8 |
|
9 def __call__(self, environ, start_response): |
|
10 # Read JSON POST input to jsonfilter.json if matching mime type |
|
11 response = {'status': '200 OK', 'headers': []} |
|
12 def json_start_response(status, headers): |
|
13 response['status'] = status |
|
14 response['headers'].extend(headers) |
|
15 environ['jsonfilter.mime_type'] = self.mime_type |
|
16 if environ.get('REQUEST_METHOD', '') == 'POST': |
|
17 if environ.get('CONTENT_TYPE', '') == self.mime_type: |
|
18 args = [_ for _ in [environ.get('CONTENT_LENGTH')] if _] |
|
19 data = environ['wsgi.input'].read(*map(int, args)) |
|
20 environ['jsonfilter.json'] = simplejson.loads(data) |
|
21 res = simplejson.dumps(self.app(environ, json_start_response)) |
|
22 jsonp = cgi.parse_qs(environ.get('QUERY_STRING', '')).get('jsonp') |
|
23 if jsonp: |
|
24 content_type = 'text/javascript' |
|
25 res = ''.join(jsonp + ['(', res, ')']) |
|
26 elif 'Opera' in environ.get('HTTP_USER_AGENT', ''): |
|
27 # Opera has bunk XMLHttpRequest support for most mime types |
|
28 content_type = 'text/plain' |
|
29 else: |
|
30 content_type = self.mime_type |
|
31 headers = [ |
|
32 ('Content-type', content_type), |
|
33 ('Content-length', len(res)), |
|
34 ] |
|
35 headers.extend(response['headers']) |
|
36 start_response(response['status'], headers) |
|
37 return [res] |
|
38 |
|
39 def factory(app, global_conf, **kw): |
|
40 return JSONFilter(app, **kw) |