Permalink
Browse files

Fix compatibility with latest WebOb

Get rid of `DECODE_PARAMS` configuration in the `Resource` class. The
`str_GET` and `str_POST` params it relied on have been removed from
WebOb.

Instead make sure POST data is only parsed if the called method accepts
parameters.
  • Loading branch information...
1 parent 3048984 commit 4171da3c53e6df69a155f864752b4930babff508 @pneff committed Jan 17, 2012
Showing with 22 additions and 25 deletions.
  1. +13 −15 tests/test_resource.py
  2. +9 −10 wsgiservice/resource.py
View
@@ -150,30 +150,28 @@ def GET(self, foo, bar):
assert obj['bar_type'] == "<type 'str'>"
-def test_no_decode_params():
- """Optionally don't decode params."""
+def test_latin1_submit():
+ """Don't access request.POST magically if method doesn't expect params.
- class User(wsgiservice.Resource):
- DECODE_PARAMS = False
+ This way if a web service wants to handle non-expected data (WebOb only
+ allows UTF-8), it can do so manually inside the method.
+ """
- @wsgiservice.validate('foo', convert=int)
- @wsgiservice.validate('bar', convert=repr)
- def GET(self, foo, bar):
- return {'foo': foo, 'foo_type': str(type(foo)),
- 'bar': bar, 'bar_type': str(type(bar))}
+ class User(wsgiservice.Resource):
+ def POST(self):
+ return {'body': repr(self.request.body)}
- req = webob.Request.blank('/?foo=193&bar=testing',
- headers={'Accept': 'application/json'})
+ req = webob.Request.blank('/test', {'REQUEST_METHOD': 'POST'},
+ headers={'Accept': 'application/json',
+ 'Content-Type': 'application/x-www-form-urlencoded'})
+ req.body = u'Fühler'.encode('latin1')
res = webob.Response()
usr = User(request=req, response=res, path_params={})
res = usr()
print res
assert res.status_int == 200
obj = json.loads(res.body)
- assert obj['foo'] is 193
- assert obj['foo_type'] == "<type 'int'>"
- assert obj['bar'] == "'testing'"
- assert obj['bar_type'] == "<type 'str'>"
+ assert obj == {'body': "'F\\xfchler'"}
def test_convert_params_validate():
View
@@ -370,28 +370,27 @@ def call_method(self, method_name):
call.
:type method_name: str
"""
- # Data is decoded by default using the encoding specified by the
- # request.
- if self.DECODE_PARAMS:
- DATA_SOURCES = [self.path_params, self.request.GET,
- self.request.POST]
- else:
- DATA_SOURCES = [self.path_params, self.request.str_GET,
- self.request.str_POST]
method = getattr(self, method_name)
+
+ request_data = []
method_params, varargs, varkw, defaults = inspect.getargspec(method)
if method_params:
method_params.pop(0) # pop the self off
+ if method_params or defaults:
+ # Read the input values, so we can call the method with keyword
+ # arguments from the request
+ request_data = [self.path_params, self.request.GET,
+ self.request.POST]
if defaults:
optional_args = method_params[-len(defaults):]
# Create a new dictionary with the keys from optional_args and
# values from defaults.
optional_args = dict(zip(optional_args, defaults))
- DATA_SOURCES.append(optional_args)
+ request_data.append(optional_args)
params = []
for param in method_params:
value = None
- for source in DATA_SOURCES:
+ for source in request_data:
if source and param in source:
value = source[param]
break

0 comments on commit 4171da3

Please sign in to comment.