diff --git a/aiohttp/web.py b/aiohttp/web.py index 366d44cba7e..3008be6e6b7 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -348,6 +348,10 @@ def post(self): self._post = MultiDictProxy(MultiDict()) return self._post + if self.headers.get('expect', '').lower() == "100-continue": + if self.version == HttpVersion11: + self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") + body = yield from self.read() content_charset = self.charset or 'utf-8' diff --git a/tests/test_web_functional.py b/tests/test_web_functional.py index 2efd291e56e..591d01270d0 100644 --- a/tests/test_web_functional.py +++ b/tests/test_web_functional.py @@ -95,6 +95,31 @@ def go(): self.loop.run_until_complete(go()) + def test_post_100_continue(self): + @asyncio.coroutine + def handler(request): + data = yield from request.post() + self.assertEqual(b'123', data['name']) + return web.Response() + + @asyncio.coroutine + def go(): + _, _, url = yield from self.create_server('POST', '/', handler) + + form = FormData() + form.add_field('name', b'123', + content_transfer_encoding='base64') + + resp = yield from request( + 'post', url, data=form, + expect100=True, # wait until server returns 100 continue + loop=self.loop) + + self.assertEqual(200, resp.status) + + self.loop.run_until_complete( + asyncio.wait_for(go(), timeout=0.1, loop=self.loop)) + def test_post_json(self): dct = {'key': 'текст'} diff --git a/tests/test_web_request.py b/tests/test_web_request.py index eddcb3eb78f..f0ec725973b 100644 --- a/tests/test_web_request.py +++ b/tests/test_web_request.py @@ -116,6 +116,42 @@ def test_call_POST_on_GET_request(self): ret = self.loop.run_until_complete(req.post()) self.assertEqual(CIMultiDict(), ret) + def test_call_POST_for_100_continue(self): + body = b"123" + req = self.make_request( + 'POST', '/', + headers=CIMultiDict({"EXPECT": "100-Continue", + 'CONTENT-TYPE': ''})) + with mock.patch.object(req, "read", side_effect=StopIteration(body)): + ret = self.loop.run_until_complete(req.post()) + self.assertEqual(ret, body) + req.transport.write.assert_called_with( + b'HTTP/1.1 100 Continue\r\n\r\n') + + def test_call_POST_for_100_continue_HTTP10(self): + body = b"123" + req = self.make_request( + 'POST', '/', + headers=CIMultiDict({"EXPECT": "100-Continue", + 'CONTENT-TYPE': ''}), + version=HttpVersion(1, 0)) + + with mock.patch.object(req, "read", side_effect=StopIteration(body)): + ret = self.loop.run_until_complete(req.post()) + self.assertEqual(ret, body) + self.assertFalse(req.transport.write.call_args_list) + + def test_call_POST_for_other_expect(self): + body = b"123" + req = self.make_request( + 'POST', '/', + headers=CIMultiDict({"EXPECT": "Other-thing", + 'CONTENT-TYPE': ''})) + with mock.patch.object(req, "read", side_effect=StopIteration(body)): + ret = self.loop.run_until_complete(req.post()) + self.assertEqual(ret, body) + self.assertFalse(req.transport.write.call_args_list) + def test_call_POST_on_weird_content_type(self): req = self.make_request( 'POST', '/',