app/django/utils/simplejson/jsonfilter.py
changeset 54 03e267d67478
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     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)