Skip to content

Commit

Permalink
resources.base: handle application/json even if params are passed in …
Browse files Browse the repository at this point in the history
…content type header

fixes #15
  • Loading branch information
swistakm committed Nov 10, 2015
1 parent 826c03a commit d30e5fb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/graceful/resources/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from falcon import errors
import falcon
from mimeparse import parse_mime_type

from graceful.parameters import BaseParam, IntParam
from graceful.errors import DeserializationError, ValidationError
Expand Down Expand Up @@ -297,13 +298,22 @@ def require_representation(self, req):
dict: raw dictionary of representation supplied in request body
"""
try:
type_, subtype, _ = parse_mime_type(req.content_type)
content_type = '/'.join((type_, subtype))
except:
raise falcon.HTTPUnsupportedMediaType(
description="Invalid Content-Type header: {}".format(
req.content_type
)
)

if req.content_type == 'application/json':
if content_type == 'application/json':
body = req.stream.read()
return json.loads(body.decode('utf-8'))
else:
raise falcon.HTTPUnsupportedMediaType(
description="only JSON supported"
description="only JSON supported, got: {}".format(content_type)
)

def require_validated(self, req, partial=False):
Expand Down
44 changes: 44 additions & 0 deletions tests/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,47 @@ class TestResource(Resource):

with pytest.raises(errors.HTTPBadRequest):
resource.require_validated(Request(env))


def test_require_representation_application_json():
resource = TestResource()

# simple application/json content type
env = create_environ(
body=json.dumps({'one': 'foo', 'two': 'foo'}),
headers={'Content-Type': 'application/json'},
)

representation = resource.require_representation(Request(env))
assert isinstance(representation, dict)

# application/json content type with charset param
env = create_environ(
body=json.dumps({'one': 'foo', 'two': 'foo'}),
headers={'Content-Type': 'application/json; charset=UTF-8'},
)

representation = resource.require_representation(Request(env))
assert isinstance(representation, dict)


def test_require_representation_unsupported_media_type():
resource = TestResource()

# invalid content type format
env = create_environ(
body=json.dumps({'one': 'foo', 'two': 'foo'}),
headers={'Content-Type': 'foo bar'},
)

with pytest.raises(falcon.HTTPUnsupportedMediaType):
resource.require_representation(Request(env))

# valid format but surely unsupported (RFC-1437)
env = create_environ(
body=json.dumps({'one': 'foo', 'two': 'foo'}),
headers={'Content-Type': 'matter-transport/sentient-life-form'},
)

with pytest.raises(falcon.HTTPUnsupportedMediaType):
resource.require_representation(Request(env))

0 comments on commit d30e5fb

Please sign in to comment.