diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 4f8e6e993..a2c0f3dd5 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -294,6 +294,8 @@ class ResponseObject(_TemplateEnvironmentMixin): ) def _bucket_response_put(self, request, body, region_name, bucket_name, querystring, headers): + if not request.headers.get('Content-Length'): + return 411, {}, "Content-Length required" if 'versioning' in querystring: ver = re.search('([A-Za-z]+)', body) if ver: @@ -355,6 +357,8 @@ class ResponseObject(_TemplateEnvironmentMixin): return 409, {}, template.render(bucket=removed_bucket) def _bucket_response_post(self, request, body, bucket_name, headers): + if not request.headers.get('Content-Length'): + return 411, {}, "Content-Length required" path = request.path if hasattr(request, 'path') else request.path_url if self.is_delete_keys(request, path, bucket_name): return self._bucket_response_delete_keys(request, body, bucket_name, headers) diff --git a/tests/test_s3/test_server.py b/tests/test_s3/test_server.py index f6b8f889c..e0440ce2f 100644 --- a/tests/test_s3/test_server.py +++ b/tests/test_s3/test_server.py @@ -66,3 +66,14 @@ def test_s3_server_post_to_bucket(): res = test_client.get('/the-key', 'http://tester.localhost:5000/') res.status_code.should.equal(200) res.data.should.equal(b"nothing") + + +def test_s3_server_post_without_content_length(): + backend = server.create_backend_app("s3") + test_client = backend.test_client() + + res = test_client.put('/', 'http://tester.localhost:5000/', environ_overrides={'CONTENT_LENGTH': ''}) + res.status_code.should.equal(411) + + res = test_client.post('/', "https://tester.localhost:5000/", environ_overrides={'CONTENT_LENGTH': ''}) + res.status_code.should.equal(411)