Commits

Robert Brewer committed 87a187b

Switched the json_in tool to take advantage of the new body.processors.

  • Participants
  • Parent commits b928806

Comments (0)

Files changed (4)

File cherrypy/_cptools.py

 _d.accept = Tool('on_start_resource', cptools.accept)
 _d.redirect = Tool('on_start_resource', cptools.redirect)
 _d.autovary = Tool('on_start_resource', cptools.autovary, priority=0)
-_d.json_in = Tool('before_handler', jsontools.json_in, priority=30)
+_d.json_in = Tool('before_request_body', jsontools.json_in, priority=30)
 _d.json_out = Tool('before_handler', jsontools.json_out, priority=30)
 _d.auth_basic = Tool('before_handler', auth_basic.basic_auth, priority=1)
 _d.auth_digest = Tool('before_handler', auth_digest.digest_auth, priority=1)

File cherrypy/lib/jsontools.py

     json_decode = json.JSONDecoder().decode
     json_encode = json.JSONEncoder().iterencode
 
-def json_in(*args, **kwargs):
+def json_in(force=True, debug=False):
     request = cherrypy.serving.request
-    _h = request.headers
-    if ('Content-Type' not in _h
-            or _h.elements('Content-Type')[0].value != 'application/json'):
-        raise cherrypy.HTTPError(415, 'Expected an application/json content type')
+    def json_processor(entity):
+        """Read application/json data into request.json."""
+        if not entity.headers.get(u"Content-Length", u""):
+            raise cherrypy.HTTPError(411)
+        
+        body = entity.fp.read()
+        try:
+            request.json = json_decode(body)
+        except ValueError:
+            raise cherrypy.HTTPError(400, 'Invalid JSON document')
+    if force:
+        request.body.processors.clear()
+        def default_proc():
+            # Leave the fp alone for someone else to read. This works fine
+            # for request.body, but the Part subclasses need to override this
+            # so they can move on to the next part.
+            raise cherrypy.HTTPError(
+                415, 'Expected an application/json content type')
+        request.body.default_proc = default_proc
+    request.body.processors[u'application/json'] = json_processor
 
-    length = int(request.headers['Content-Length'])
-    body = request.body.read(length)
-
-    try:
-        json = json_decode(body)
-    except ValueError:
-        raise cherrypy.HTTPError(400, 'Invalid JSON document')
-
-    request.json = json
-
-def json_out(*args, **kwargs):
+def json_out(debug=False):
     request = cherrypy.serving.request
     response = cherrypy.serving.response
-
+    
     real_handler = request.handler
     def json_handler(*args, **kwargs):
         response.headers['Content-Type'] = 'application/json'
         value = real_handler(*args, **kwargs)
         return json_encode(value)
     request.handler = json_handler
+

File cherrypy/test/test_json.py

 
         def test_json_input(self):
             body = '[13, "c"]'
-            headers = [('Content-Type', 'application/json'), ('Content-Length', str(len(body)))]
+            headers = [('Content-Type', 'application/json'),
+                       ('Content-Length', str(len(body)))]
             self.getPage("/json_post", method="POST", headers=headers, body=body)
             self.assertBody('ok')
-
-            self.getPage("/json_post")
+            
+            body = '[13, "c"]'
+            headers = [('Content-Type', 'text/plain'),
+                       ('Content-Length', str(len(body)))]
+            self.getPage("/json_post", method="POST", headers=headers, body=body)
             self.assertStatus(415, 'Expected an application/json content type')
-
+            
             body = '[13, -]'
-            headers = [('Content-Type', 'application/json'), ('Content-Length', str(len(body)))]
+            headers = [('Content-Type', 'application/json'),
+                       ('Content-Length', str(len(body)))]
             self.getPage("/json_post", method="POST", headers=headers, body=body)
             self.assertStatus(400, 'Invalid JSON document')
 

File cherrypy/tutorial/tut09_files.py

         
         # Although this just counts the file length, it demonstrates
         # how to read large files in chunks instead of all at once.
-        # CherryPy uses Python's cgi module to read the uploaded file
-        # into a temporary file; myFile.file.read reads from that.
+        # CherryPy reads the uploaded file into a temporary file;
+        # myFile.file.read reads from that.
         size = 0
         while True:
             data = myFile.file.read(8192)