Skip to content

Commit

Permalink
Async write headers (#2762)
Browse files Browse the repository at this point in the history
* Make _start a coroutine

* Make write_headers a coroutine

* Add change note
  • Loading branch information
asvetlov authored Feb 26, 2018
1 parent f38e14c commit 0a94431
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 76 deletions.
1 change: 1 addition & 0 deletions CHANGES/2762.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make ``writer.write_headers`` a coroutine.
2 changes: 1 addition & 1 deletion aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ async def send(self, conn):
# status + headers
status_line = '{0} {1} HTTP/{2[0]}.{2[1]}\r\n'.format(
self.method, path, self.version)
writer.write_headers(status_line, self.headers)
await writer.write_headers(status_line, self.headers)

self._writer = self.loop.create_task(self.write_bytes(writer, conn))

Expand Down
2 changes: 1 addition & 1 deletion aiohttp/http_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def write(self, chunk, *, drain=True, LIMIT=64*1024):

return noop()

def write_headers(self, status_line, headers, SEP=': ', END='\r\n'):
async def write_headers(self, status_line, headers, SEP=': ', END='\r\n'):
"""Write request/response status and headers."""
# status + headers
headers = status_line + ''.join(
Expand Down
13 changes: 5 additions & 8 deletions aiohttp/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ def make_mocked_request(method, path, headers=None, *,
version=HttpVersion(1, 1), closing=False,
app=None,
writer=sentinel,
payload_writer=sentinel,
protocol=sentinel,
transport=sentinel,
payload=sentinel,
Expand Down Expand Up @@ -509,22 +508,20 @@ def make_mocked_request(method, path, headers=None, *,

if writer is sentinel:
writer = mock.Mock()
writer.write_headers = make_mocked_coro(None)
writer.write = make_mocked_coro(None)
writer.write_eof = make_mocked_coro(None)
writer.drain = make_mocked_coro(None)
writer.transport = transport

if payload_writer is sentinel:
payload_writer = mock.Mock()
payload_writer.write = make_mocked_coro(None)
payload_writer.write_eof = make_mocked_coro(None)
payload_writer.drain = make_mocked_coro(None)

protocol.transport = transport
protocol.writer = writer

if payload is sentinel:
payload = mock.Mock()

req = Request(message, payload,
protocol, payload_writer, task, loop,
protocol, writer, task, loop,
client_max_size=client_max_size)

match_info = UrlMappingMatchInfo(
Expand Down
32 changes: 16 additions & 16 deletions aiohttp/web_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,19 @@ async def prepare(self, request):
return self._payload_writer

await request._prepare_hook(self)
return self._start(request)

def _start(self, request,
HttpVersion10=HttpVersion10,
HttpVersion11=HttpVersion11,
CONNECTION=hdrs.CONNECTION,
DATE=hdrs.DATE,
SERVER=hdrs.SERVER,
CONTENT_TYPE=hdrs.CONTENT_TYPE,
CONTENT_LENGTH=hdrs.CONTENT_LENGTH,
SET_COOKIE=hdrs.SET_COOKIE,
SERVER_SOFTWARE=SERVER_SOFTWARE,
TRANSFER_ENCODING=hdrs.TRANSFER_ENCODING):
return await self._start(request)

async def _start(self, request,
HttpVersion10=HttpVersion10,
HttpVersion11=HttpVersion11,
CONNECTION=hdrs.CONNECTION,
DATE=hdrs.DATE,
SERVER=hdrs.SERVER,
CONTENT_TYPE=hdrs.CONTENT_TYPE,
CONTENT_LENGTH=hdrs.CONTENT_LENGTH,
SET_COOKIE=hdrs.SET_COOKIE,
SERVER_SOFTWARE=SERVER_SOFTWARE,
TRANSFER_ENCODING=hdrs.TRANSFER_ENCODING):
self._req = request

keep_alive = self._keep_alive
Expand Down Expand Up @@ -364,7 +364,7 @@ def _start(self, request,
# status line
status_line = 'HTTP/{}.{} {} {}\r\n'.format(
version[0], version[1], self._status, self._reason)
writer.write_headers(status_line, headers)
await writer.write_headers(status_line, headers)

return writer

Expand Down Expand Up @@ -594,15 +594,15 @@ async def write_eof(self):
else:
await super().write_eof()

def _start(self, request):
async def _start(self, request):
if not self._chunked and hdrs.CONTENT_LENGTH not in self._headers:
if not self._body_payload:
if self._body is not None:
self._headers[hdrs.CONTENT_LENGTH] = str(len(self._body))
else:
self._headers[hdrs.CONTENT_LENGTH] = '0'

return super()._start(request)
return await super()._start(request)

def _do_start_compression(self, coding):
if self._body_payload or self._chunked:
Expand Down
4 changes: 4 additions & 0 deletions tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from aiohttp import BaseConnector, hdrs, payload
from aiohttp.client_reqrep import (ClientRequest, ClientResponse, Fingerprint,
_merge_ssl_params)
from aiohttp.test_utils import make_mocked_coro


@pytest.fixture
Expand Down Expand Up @@ -668,6 +669,7 @@ async def test_content_encoding(loop, conn):
req = ClientRequest('post', URL('http://python.org/'), data='foo',
compress='deflate', loop=loop)
with mock.patch('aiohttp.client_reqrep.StreamWriter') as m_writer:
m_writer.return_value.write_headers = make_mocked_coro()
resp = await req.send(conn)
assert req.headers['TRANSFER-ENCODING'] == 'chunked'
assert req.headers['CONTENT-ENCODING'] == 'deflate'
Expand All @@ -693,6 +695,7 @@ async def test_content_encoding_header(loop, conn):
'post', URL('http://python.org/'), data='foo',
headers={'Content-Encoding': 'deflate'}, loop=loop)
with mock.patch('aiohttp.client_reqrep.StreamWriter') as m_writer:
m_writer.return_value.write_headers = make_mocked_coro()
resp = await req.send(conn)

assert not m_writer.return_value.enable_compression.called
Expand Down Expand Up @@ -732,6 +735,7 @@ async def test_chunked_explicit(loop, conn):
req = ClientRequest(
'post', URL('http://python.org/'), chunked=True, loop=loop)
with mock.patch('aiohttp.client_reqrep.StreamWriter') as m_writer:
m_writer.return_value.write_headers = make_mocked_coro()
resp = await req.send(conn)

assert 'chunked' == req.headers['TRANSFER-ENCODING']
Expand Down
4 changes: 2 additions & 2 deletions tests/test_web_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def append(data=b''):
buf.extend(data)
return helpers.noop()

def write_headers(status_line, headers):
async def write_headers(status_line, headers):
headers = status_line + ''.join(
[k + ': ' + v + '\r\n' for k, v in headers.items()])
headers = headers.encode('utf-8') + b'\r\n'
Expand All @@ -39,7 +39,7 @@ def write_headers(status_line, headers):
app._debug = False
app.on_response_prepare = signals.Signal(app)
app.on_response_prepare.freeze()
req = make_mocked_request(method, path, app=app, payload_writer=writer)
req = make_mocked_request(method, path, app=app, writer=writer)
return req


Expand Down
Loading

0 comments on commit 0a94431

Please sign in to comment.