Commits

Anonymous committed 77faa7c

o don't consider PUT requests with an empty content-type as form requests
o update req.POST's docstring per new PUT support, move its example into
reference.txt
thanks Ian

Comments (0)

Files changed (5)

 
 * Fixed ``resp.set_cookie(max_age=timedelta(...))``
 
+* ``request.POST`` now supports PUT requests with the appropriate
+  Content-Type.
+
 0.9.2
 -----
 

docs/reference.txt

 .. code-block:: python
 
     >>> req.POST
-    <NoVars: Not a POST or form request>
+    <NoVars: Not a form request>
     >>> req.POST.items()  # NoVars can be read like a dict, but not written
     []
     >>> req.method = 'POST'
     name: 'Joe'
     email: 'joe@example.com'
 
+The ``POST`` and ``GET`` nomenclature is historical -- ``req.GET`` can
+be used for non-GET requests to access query parameters, and
+``req.POST`` can also be used for PUT requests with the appropriate
+Content-Type.
+
+    >>> req = Request.blank('/test?check=a&check=b&name=Bob')
+    >>> req.method = 'PUT'
+    >>> req.body = body = 'var1=value1&var2=value2&rep=1&rep=2'
+    >>> req.environ['CONTENT_LENGTH'] = str(len(req.body))
+    >>> req.environ['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
+    >>> req.GET
+    MultiDict([('check', 'a'), ('check', 'b'), ('name', 'Bob')])
+    >>> req.POST
+    MultiDict([('var1', 'value1'), ('var2', 'value2'), ('rep', '1'), ('rep', '2')])
+
 Unicode Variables
 ~~~~~~~~~~~~~~~~~
 

tests/test_request.py

     print res
     assert 'Hello' in res
     assert "get is MultiDict([])" in res
-    assert "post is <NoVars: Not a POST or form request>" in res
+    assert "post is <NoVars: Not a form request>" in res
     
     res = app.get('/?name=george')
     res.mustcontain("get is MultiDict([('name', 'george')])")

tests/test_request.txt

     >>> req.POST
     UnicodeMultiDict([('var1', u'value1'), ('var2', u'value2'), ('rep', u'1'), ('rep', u'2')])
 
-The ``POST`` and ``GET`` nomenclature for request variables is
-historical -- ``request.GET`` can be used in non GET requests to
-access query parameters, and ``request.POST`` can be used in PUT form
-requests.
-
-    >>> body = 'var1=value1&var2=value2&rep=1&rep=2'
-    >>> req = Request.blank('/?foo=bar')
-    >>> req.method = 'PUT'
-    >>> req.body_file = StringIO(body)
-    >>> req.environ['CONTENT_LENGTH'] = str(len(body))
-    >>> req.environ['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
-    >>> req.POST
-    MultiDict([('var1', 'value1'), ('var2', 'value2'), ('rep', '1'), ('rep', '2')])
-    >>> req.GET
-    MultiDict([('foo', 'bar')])
-
 Note that the variables are there for GET requests and non-form requests,
 but they are empty and read-only:
 
     >>> req = Request.blank('/')
     >>> req.str_POST
-    <NoVars: Not a POST or form request>
+    <NoVars: Not a form request>
     >>> req.str_POST.items()
     []
     >>> req.str_POST['x'] = 'y'
     Traceback (most recent call last):
         ...
-    KeyError: 'Cannot add variables: Not a POST or form request'
+    KeyError: 'Cannot add variables: Not a form request'
     >>> req.method = 'POST'
     >>> req.str_POST
     MultiDict([])

webob/__init__.py

 
     def str_POST(self):
         """
-        Return a MultiDict containing all the variables from a POST
-        form request.  Does *not* return anything for non-POST
-        requests or for non-form requests (returns empty dict-like
-        object in that case).
+        Return a MultiDict containing all the variables from a form
+        request. Returns an empty dict-like object for non-form
+        requests.
+
+        Form requests are typically POST requests, however PUT requests
+        with an appropriate Content-Type are also supported.
         """
         env = self.environ
         if self.method not in ('POST', 'PUT'):
-            return NoVars('Not a POST or form request')
+            return NoVars('Not a form request')
         if 'webob._parsed_post_vars' in env:
             vars, body_file = env['webob._parsed_post_vars']
             if body_file is self.body_file:
         content_type = self.content_type
         if ';' in content_type:
             content_type = content_type.split(';', 1)[0]
-        if content_type not in ('', 'application/x-www-form-urlencoded',
-                                'multipart/form-data'):
+        if (self.method == 'PUT' and not content_type) or \
+                content_type not in ('', 'application/x-www-form-urlencoded',
+                                     'multipart/form-data'):
             # Not an HTML form submission
             return NoVars('Not an HTML form submission (Content-Type: %s)'
                           % content_type)