diff --git a/djangorestframework/request.py b/djangorestframework/request.py index c5d982860..f79354a1e 100644 --- a/djangorestframework/request.py +++ b/djangorestframework/request.py @@ -1,4 +1,8 @@ from djangorestframework.mediatypes import MediaType +from djangorestframework.utils import as_tuple +from djangorestframework.response import ResponseException +from djangorestframework import status + #from djangorestframework.requestparsing import parse, load_parser from django.http.multipartparser import LimitBytes from StringIO import StringIO @@ -11,6 +15,8 @@ class RequestMixin(object): CONTENTTYPE_PARAM = "_content_type" CONTENT_PARAM = "_content" + parsers = () + def _get_method(self): """ Returns the HTTP method for the current view. @@ -33,7 +39,10 @@ class RequestMixin(object): """ if not hasattr(self, '_content_type'): content_type = self.request.META.get('HTTP_CONTENT_TYPE', self.request.META.get('CONTENT_TYPE', '')) - self._content_type = MediaType(content_type) + if content_type: + self._content_type = MediaType(content_type) + else: + self._content_type = None return self._content_type @@ -68,8 +77,15 @@ class RequestMixin(object): if not hasattr(self, '_stream'): request = self.request + try: + content_length = int(request.META.get('CONTENT_LENGTH', request.META.get('HTTP_CONTENT_LENGTH'))) + except (ValueError, TypeError): + content_length = 0 + # Currently only supports parsing request body as a stream with 1.3 - if hasattr(request, 'read'): + if content_length == 0: + return None + elif hasattr(request, 'read'): # It's not at all clear if this needs to be byte limited or not. # Maybe I'm just being dumb but it looks to me like there's some issues # with that in Django. @@ -152,6 +168,9 @@ class RequestMixin(object): May raise a 415 ResponseException (Unsupported Media Type), or a 400 ResponseException (Bad Request). """ + if stream is None or content_type is None: + return None + parsers = as_tuple(self.parsers) parser = None diff --git a/djangorestframework/tests/content.py b/djangorestframework/tests/content.py index 31fcf892e..5e77472da 100644 --- a/djangorestframework/tests/content.py +++ b/djangorestframework/tests/content.py @@ -2,6 +2,7 @@ from django.test import TestCase from djangorestframework.compat import RequestFactory from djangorestframework.request import RequestMixin +from djangorestframework.parsers import FormParser, MultipartParser #from djangorestframework.content import ContentMixin, StandardContentMixin, OverloadedContentMixin # # @@ -31,16 +32,17 @@ class TestContentMixins(TestCase): # # Common functionality to test with both StandardContentMixin and OverloadedContentMixin # def ensure_determines_no_content_GET(self, view): - """Ensure determine_content(request) returns None for GET request with no content.""" + """Ensure view.RAW_CONTENT returns None for GET request with no content.""" view.request = self.req.get('/') self.assertEqual(view.RAW_CONTENT, None) -# -# def ensure_determines_form_content_POST(self, mixin): -# """Ensure determine_content(request) returns content for POST request with content.""" -# form_data = {'qwerty': 'uiop'} -# request = self.req.post('/', data=form_data) -# self.assertEqual(mixin.determine_content(request), (request.META['CONTENT_TYPE'], request.raw_post_data)) -# + + def ensure_determines_form_content_POST(self, view): + """Ensure determine_content(request) returns content for POST request with content.""" + form_data = {'qwerty': 'uiop'} + view.parsers = (FormParser, MultipartParser) + view.request = self.req.post('/', data=form_data) + self.assertEqual(view.RAW_CONTENT, form_data) + # def ensure_determines_non_form_content_POST(self, mixin): # """Ensure determine_content(request) returns (content type, content) for POST request with content.""" # content = 'qwerty' @@ -64,12 +66,12 @@ class TestContentMixins(TestCase): # # StandardContentMixin behavioural tests # def test_standard_behaviour_determines_no_content_GET(self): - """Ensure StandardContentMixin.determine_content(request) returns None for GET request with no content.""" + """Ensure request.RAW_CONTENT returns None for GET request with no content.""" self.ensure_determines_no_content_GET(RequestMixin()) -# -# def test_standard_behaviour_determines_form_content_POST(self): -# """Ensure StandardContentMixin.determine_content(request) returns content for POST request with content.""" -# self.ensure_determines_form_content_POST(StandardContentMixin()) + + def test_standard_behaviour_determines_form_content_POST(self): + """Ensure request.RAW_CONTENT returns content for POST request with content.""" + self.ensure_determines_form_content_POST(RequestMixin()) # # def test_standard_behaviour_determines_non_form_content_POST(self): # """Ensure StandardContentMixin.determine_content(request) returns (content type, content) for POST request with content."""