Home | History | Annotate | Download | only in simplejson
      1 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)
     41