From 583686cd060c3409df52c2868da5740c61162ade Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Tue, 26 May 2015 22:59:45 -0400 Subject: [PATCH 1/3] Ensure form overloading performs parsing. --- rest_framework/request.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/rest_framework/request.py b/rest_framework/request.py index e4b5bc263..5f87060e8 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -380,29 +380,27 @@ class Request(object): ): return - # At this point we're committed to parsing the request as form data. - self._data = self._request.POST - self._files = self._request.FILES - self._full_data = self._data.copy() - self._full_data.update(self._files) + # Reading the request body before directly accessing the POST attr will + # ensure the request body is stored, making it accessible again later. + self._request.body + data = self._request.POST # Method overloading - change the method and remove the param from the content. if ( self._METHOD_PARAM and - self._METHOD_PARAM in self._data + self._METHOD_PARAM in data ): - self._method = self._data[self._METHOD_PARAM].upper() + self._method = data[self._METHOD_PARAM].upper() # Content overloading - modify the content type, and force re-parse. if ( self._CONTENT_PARAM and self._CONTENTTYPE_PARAM and - self._CONTENT_PARAM in self._data and - self._CONTENTTYPE_PARAM in self._data + self._CONTENT_PARAM in data and + self._CONTENTTYPE_PARAM in data ): - self._content_type = self._data[self._CONTENTTYPE_PARAM] - self._stream = six.BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) - self._data, self._files, self._full_data = (Empty, Empty, Empty) + self._content_type = data[self._CONTENTTYPE_PARAM] + self._stream = six.BytesIO(data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) def _parse(self): """ From fdc0711812d87f11a5e8aac69206c0b05ca65b37 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Wed, 27 May 2015 12:33:56 -0400 Subject: [PATCH 2/3] Updated documentation on calling _request.body --- rest_framework/request.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest_framework/request.py b/rest_framework/request.py index 5f87060e8..f45a201f7 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -382,6 +382,9 @@ class Request(object): # Reading the request body before directly accessing the POST attr will # ensure the request body is stored, making it accessible again later. + # DRF uses multipart/form-data by default, which triggers an optimization + # in the underlying django request. For more details: + # https://github.com/django/django/blob/1.8.2/tests/requests/tests.py#L353-L372 self._request.body data = self._request.POST From 290de9695aa2c6eb9a14e4d1a48ff116358d2af3 Mon Sep 17 00:00:00 2001 From: Ryan P Kilby Date: Fri, 29 May 2015 21:43:00 -0400 Subject: [PATCH 3/3] Added setting flag to use form parsing --- rest_framework/request.py | 11 +++++++++-- rest_framework/settings.py | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rest_framework/request.py b/rest_framework/request.py index f45a201f7..1cd919efd 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -385,8 +385,15 @@ class Request(object): # DRF uses multipart/form-data by default, which triggers an optimization # in the underlying django request. For more details: # https://github.com/django/django/blob/1.8.2/tests/requests/tests.py#L353-L372 - self._request.body - data = self._request.POST + if api_settings.FORM_OVERRIDE_DO_PARSE: + self._request.body + data = self._request.POST + else: + self._data = self._request.POST + self._files = self._request.FILES + self._full_data = self._data.copy() + self._full_data.update(self._files) + data = self._data # Method overloading - change the method and remove the param from the content. if ( diff --git a/rest_framework/settings.py b/rest_framework/settings.py index a3e9f5902..6541be267 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -92,6 +92,7 @@ DEFAULTS = { 'TEST_REQUEST_DEFAULT_FORMAT': 'multipart', # Browser enhancements + 'FORM_OVERRIDE_DO_PARSE': False, 'FORM_METHOD_OVERRIDE': '_method', 'FORM_CONTENT_OVERRIDE': '_content', 'FORM_CONTENTTYPE_OVERRIDE': '_content_type',