Commits

Adam Lowry committed 5f2e107

POSTs and PUTs with invalid data for the content-type return 400 Bad Request

  • Participants
  • Parent commits 9cf7ef7

Comments (0)

Files changed (3)

File piston/resource.py

 from doc import HandlerMethod
 from authentication import NoAuthentication
 from utils import coerce_put_post, FormValidationError, HttpStatusCode
-from utils import rc, format_error, translate_mime
+from utils import rc, format_error, translate_mime, MimerDataException
 
 class Resource(object):
     """
             anonymous = handler.is_anonymous
         
         # Translate nested datastructs into `request.data` here.
-        translate_mime(request)
+        if rm in ('POST', 'PUT'):
+            try:
+                translate_mime(request)
+            except MimerDataException:
+                return rc.BAD_REQUEST
         
         if not rm in handler.allowed_methods:
             return HttpResponseNotAllowed(handler.allowed_methods)

File piston/utils.py

-from django.http import HttpResponseNotAllowed, HttpResponseForbidden, HttpResponse
+from django.http import (HttpResponseNotAllowed, HttpResponseForbidden,
+    HttpResponse, HttpResponseBadRequest)
 from django.core.urlresolvers import reverse
 from django.core.cache import cache
 from django import get_version as django_version
             
         request.PUT = request.POST
 
+
+class MimerDataException(Exception):
+    """Raised if the content_type and data don't match"""
+
+
 class Mimer(object):
     TYPES = dict()
     
                 # Reset both POST and PUT from request, as its
                 # misleading having their presence around.
                 self.request.POST = self.request.PUT = dict()
-            except TypeError:
-                return rc.BAD_REQUEST # TODO: Handle this in super
-            except Exception, e:
-                raise
-                
+            except (TypeError, ValueError):
+                raise MimerDataException
+
         return self.request
                 
     @classmethod

File tests/test_project/apps/testapp/tests.py

             HTTP_AUTHORIZATION=self.auth_string).content
             
         self.assertEquals(result, expected)
-        
+
+    def test_incoming_invalid_json(self):
+        resp = self.client.post('/api/expressive.json',
+            'foo',
+            HTTP_AUTHORIZATION=self.auth_string,
+            content_type='application/json')
+        self.assertEquals(resp.status_code, 400)
+
     def test_incoming_yaml(self):
         if not yaml:
             return
         self.assertEquals(self.client.get('/api/expressive.yaml', 
             HTTP_AUTHORIZATION=self.auth_string).content, expected)
 
+    def test_incoming_invalid_yaml(self):
+        resp = self.client.post('/api/expressive.yaml',
+            '  8**sad asj lja foo',
+            HTTP_AUTHORIZATION=self.auth_string,
+            content_type='application/yaml')
+        self.assertEquals(resp.status_code, 400)
+
 class Issue36RegressionTests(MainTests):
     """
     This testcase addresses #36 in django-piston where request.FILES is passed