diff options
Diffstat (limited to 'flywheel/parsers.py')
| -rw-r--r-- | flywheel/parsers.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/flywheel/parsers.py b/flywheel/parsers.py new file mode 100644 index 00000000..f0684612 --- /dev/null +++ b/flywheel/parsers.py @@ -0,0 +1,80 @@ +from flywheel.response import status, ResponseException + +try: + import json +except ImportError: + import simplejson as json + +# TODO: Make all parsers only list a single media_type, rather than a list + +class BaseParser(object): + media_types = () + + def __init__(self, resource): + self.resource = resource + + def parse(self, input): + return {} + + +class JSONParser(BaseParser): + media_types = ('application/xml',) + + def parse(self, input): + try: + return json.loads(input) + except ValueError, exc: + raise ResponseException(status.HTTP_400_BAD_REQUEST, {'detail': 'JSON parse error - %s' % str(exc)}) + +class XMLParser(BaseParser): + media_types = ('application/xml',) + + +class FormParser(BaseParser): + """The default parser for form data. + Return a dict containing a single value for each non-reserved parameter. + """ + + media_types = ('application/x-www-form-urlencoded',) + + 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 + + if request.method == 'PUT': + # Fix from piston to force Django to give PUT requests the same + # form processing that POST requests get... + # + # Bug fix: if _load_post_and_files has already been called, for + # example by middleware accessing request.POST, the below code to + # pretend the request is a POST instead of a PUT will be too late + # to make a difference. Also calling _load_post_and_files will result + # in the following exception: + # 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 + data = {} + for (key, val) in request.POST.items(): + if key not in self.resource.RESERVED_FORM_PARAMS: + data[key] = val + + return data + + |
