Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Allow empty bodies on POST/PUT/PATCH requests in simple_httpclient #719

wants to merge 2 commits into from

2 participants


Currently, POST/PATCH/PUT requests with simple_httpclient will error out if there is no request body. As far as I know, it is valid to make requests with these verbs and not have a body:

This removes that requirement, and adds a test that empty bodies are allowed.


There is always a body for POST/PUT/etc, but it may be empty. Since this is relatively rare and it is likely to be an error to specify a POST without a body, Tornado requires you to say body="" if that is what you want.

@bdarnell bdarnell closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
5 tornado/
@@ -249,11 +249,6 @@ def _on_connect(self):
if self.request.user_agent:
self.request.headers["User-Agent"] = self.request.user_agent
- if not self.request.allow_nonstandard_methods:
- if self.request.method in ("POST", "PATCH", "PUT"):
- assert self.request.body is not None
- else:
- assert self.request.body is None
if self.request.body is not None:
self.request.headers["Content-Length"] = str(len(
11 tornado/test/
@@ -93,6 +93,11 @@ def get(self):
+class EmptyBodyHandler(RequestHandler):
+ def post(self):
+ self.write("ok")
class SimpleHTTPClientTestCase(AsyncHTTPTestCase):
def setUp(self):
super(SimpleHTTPClientTestCase, self).setUp()
@@ -115,6 +120,7 @@ def get_app(self):
url("/see_other_post", SeeOtherPostHandler),
url("/see_other_get", SeeOtherGetHandler),
url("/host_echo", HostEchoHandler),
+ url("/expecting_empty_body", EmptyBodyHandler)
], gzip=True)
def test_singleton(self):
@@ -288,6 +294,11 @@ def test_host_header(self):
response = self.wait()
self.assertTrue(host_re.match(response.body), response.body)
+ def test_empty_body(self):
+ response = self.fetch("/expecting_empty_body", method="POST")
+ self.assertEqual(response.code, 200)
+ self.assertEqual(response.body, b'ok')
def test_connection_refused(self):
server_socket, port = bind_unused_port()
Something went wrong with that request. Please try again.