Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
91b33659
Commit
91b33659
authored
Mar 04, 2011
by
spiq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix for PUT files
parent
30fd23d7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
37 deletions
+80
-37
djangorestframework/content.py
+32
-4
djangorestframework/parsers.py
+48
-33
No files found.
djangorestframework/content.py
View file @
91b33659
...
@@ -24,6 +24,27 @@ class StandardContentMixin(ContentMixin):
...
@@ -24,6 +24,27 @@ class StandardContentMixin(ContentMixin):
return
None
return
None
return
(
request
.
META
.
get
(
'CONTENT_TYPE'
,
None
),
request
.
raw_post_data
)
return
(
request
.
META
.
get
(
'CONTENT_TYPE'
,
None
),
request
.
raw_post_data
)
from
django.core.files.base
import
File
class
SocketFile
(
File
):
# Only forward access is allowed
def
__init__
(
self
,
socket
,
size
):
super
(
SocketFile
,
self
)
.
__init__
(
socket
)
self
.
_size
=
int
(
size
)
self
.
_pos
=
0
def
read
(
self
,
num_bytes
=
None
):
if
num_bytes
is
None
:
num_bytes
=
self
.
_size
-
self
.
_pos
else
:
num_bytes
=
min
(
num_bytes
,
self
.
_size
-
self
.
_pos
)
self
.
_pos
+=
num_bytes
return
self
.
file
.
read
(
num_bytes
)
def
tell
(
self
):
return
self
.
_pos
def
seek
(
self
,
position
):
pass
class
OverloadedContentMixin
(
ContentMixin
):
class
OverloadedContentMixin
(
ContentMixin
):
"""HTTP request content behaviour that also allows arbitrary content to be tunneled in form data."""
"""HTTP request content behaviour that also allows arbitrary content to be tunneled in form data."""
...
@@ -39,7 +60,7 @@ class OverloadedContentMixin(ContentMixin):
...
@@ -39,7 +60,7 @@ class OverloadedContentMixin(ContentMixin):
Note that content_type may be None if it is unset."""
Note that content_type may be None if it is unset."""
if
not
request
.
META
.
get
(
'CONTENT_LENGTH'
,
None
)
and
not
request
.
META
.
get
(
'TRANSFER_ENCODING'
,
None
):
if
not
request
.
META
.
get
(
'CONTENT_LENGTH'
,
None
)
and
not
request
.
META
.
get
(
'TRANSFER_ENCODING'
,
None
):
return
None
return
None
content_type
=
request
.
META
.
get
(
'CONTENT_TYPE'
,
None
)
content_type
=
request
.
META
.
get
(
'CONTENT_TYPE'
,
None
)
if
(
request
.
method
==
'POST'
and
self
.
CONTENT_PARAM
and
if
(
request
.
method
==
'POST'
and
self
.
CONTENT_PARAM
and
...
@@ -51,5 +72,13 @@ class OverloadedContentMixin(ContentMixin):
...
@@ -51,5 +72,13 @@ class OverloadedContentMixin(ContentMixin):
content_type
=
request
.
POST
.
get
(
self
.
CONTENTTYPE_PARAM
,
None
)
content_type
=
request
.
POST
.
get
(
self
.
CONTENTTYPE_PARAM
,
None
)
return
(
content_type
,
request
.
POST
[
self
.
CONTENT_PARAM
])
return
(
content_type
,
request
.
POST
[
self
.
CONTENT_PARAM
])
elif
request
.
method
==
'PUT'
:
return
(
content_type
,
request
.
raw_post_data
)
f
=
SocketFile
(
request
.
environ
[
'wsgi.input'
],
request
.
META
[
'CONTENT_LENGTH'
])
\ No newline at end of file
returned
=
(
content_type
,
f
.
read
())
return
returned
#try:
# f.close()
#except Exception as e:
# print 'exception', e
else
:
return
(
content_type
,
request
.
raw_post_data
)
djangorestframework/parsers.py
View file @
91b33659
from
StringIO
import
StringIO
from
django.http.multipartparser
import
MultiPartParser
as
DjangoMPParser
from
djangorestframework.response
import
ResponseException
from
djangorestframework.response
import
ResponseException
from
djangorestframework
import
status
from
djangorestframework
import
status
...
@@ -6,6 +10,10 @@ try:
...
@@ -6,6 +10,10 @@ try:
except
ImportError
:
except
ImportError
:
import
simplejson
as
json
import
simplejson
as
json
try
:
from
urlparse
import
parse_qs
except
ImportError
:
from
cgi
import
parse_qs
class
ParserMixin
(
object
):
class
ParserMixin
(
object
):
parsers
=
()
parsers
=
()
...
@@ -75,50 +83,57 @@ class FormParser(BaseParser):
...
@@ -75,50 +83,57 @@ class FormParser(BaseParser):
"""The default parser for form data.
"""The default parser for form data.
Return a dict containing a single value for each non-reserved parameter.
Return a dict containing a single value for each non-reserved parameter.
"""
"""
# TODO: not good, because posted/put lists are flattened !!!
media_type
=
'application/x-www-form-urlencoded'
media_type
=
'application/x-www-form-urlencoded'
def
parse
(
self
,
input
):
def
parse
(
self
,
input
):
# The FormParser doesn't parse the input as other parsers would, since Django's already done the
# form parsing for us. We build the content object from the request directly.
request
=
self
.
resource
.
request
request
=
self
.
resource
.
request
if
request
.
method
==
'PUT'
:
if
request
.
method
==
'PUT'
:
# Fix from piston to force Django to give PUT requests the same
data
=
parse_qs
(
input
)
# form processing that POST requests get...
# Flattening the parsed query data
#
for
key
,
val
in
data
.
items
():
# Bug fix: if _load_post_and_files has already been called, for
data
[
key
]
=
val
[
0
]
# example by middleware accessing request.POST, the below code to
# pretend the request is a POST instead of a PUT will be too late
if
request
.
method
==
'POST'
:
# to make a difference. Also calling _load_post_and_files will result
# Django has already done the form parsing for us.
# in the following exception:
data
=
dict
(
request
.
POST
.
items
())
# AttributeError: You cannot set the upload handlers after the upload has been processed.
# The fix is to check for the presence of the _post field which is set
# the first time _load_post_and_files is called (both by wsgi.py and
# modpython.py). If it's set, the request has to be 'reset' to redo
# the query value parsing in POST mode.
if
hasattr
(
request
,
'_post'
):
del
request
.
_post
del
request
.
_files
try
:
request
.
method
=
"POST"
request
.
_load_post_and_files
()
request
.
method
=
"PUT"
except
AttributeError
:
request
.
META
[
'REQUEST_METHOD'
]
=
'POST'
request
.
_load_post_and_files
()
request
.
META
[
'REQUEST_METHOD'
]
=
'PUT'
# Strip any parameters that we are treating as reserved
# Strip any parameters that we are treating as reserved
data
=
{}
for
key
in
data
:
for
(
key
,
val
)
in
request
.
POST
.
items
():
if
key
in
self
.
resource
.
RESERVED_FORM_PARAMS
:
if
key
not
in
self
.
resource
.
RESERVED_FORM_PARAMS
:
data
.
pop
(
key
)
data
[
key
]
=
val
return
data
return
data
# TODO: Allow parsers to specify multiple media_types
# TODO: Allow parsers to specify multiple media_types
class
MultipartParser
(
FormParser
):
class
MultipartParser
(
FormParser
):
media_type
=
'multipart/form-data'
media_type
=
'multipart/form-data'
def
parse
(
self
,
input
):
request
=
self
.
resource
.
request
if
request
.
method
==
'PUT'
:
upload_handlers
=
request
.
_get_upload_handlers
()
django_mpp
=
DjangoMPParser
(
request
.
META
,
StringIO
(
input
),
upload_handlers
)
data
,
files
=
django_mpp
.
parse
()
data
=
dict
(
data
)
files
=
dict
(
files
)
if
request
.
method
==
'POST'
:
# Django has already done the form parsing for us.
data
=
dict
(
request
.
POST
)
files
=
dict
(
request
.
FILES
)
# Flattening, then merging the POSTED/PUT data/files
for
key
,
val
in
dict
(
data
)
.
items
():
data
[
key
]
=
val
[
0
]
for
key
,
val
in
dict
(
files
)
.
items
():
files
[
key
]
=
val
[
0
]
.
read
()
data
.
update
(
files
)
# Strip any parameters that we are treating as reserved
for
key
in
data
:
if
key
in
self
.
resource
.
RESERVED_FORM_PARAMS
:
data
.
pop
(
key
)
return
data
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment