Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resp prepare #525

Merged
merged 8 commits into from
Sep 25, 2015
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aiohttp/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def handle_request(self, message, payload):
except HTTPException as exc:
resp = exc

resp_msg = resp.start(request)
resp_msg = yield from resp.prepare(request)
yield from resp.write_eof()

# notify server about keep-alive
Expand Down
19 changes: 18 additions & 1 deletion aiohttp/web_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,14 @@ def _copy_cookies(self):
self.headers.add(hdrs.SET_COOKIE, value)

@property
def started(self):
def prepared(self):
return self._resp_impl is not None

@property
def started(self):
warnings.warn('use Response.prepared instead', DeprecationWarning)
return self.prepared

@property
def status(self):
return self._status
Expand Down Expand Up @@ -629,10 +634,22 @@ def start(coding):
return

def start(self, request):
warnings.warn('use .prepare(request) instead', DeprecationWarning)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems .start remain plain old function while .prepare is coroutine. Are they really interchangeable during deprecation period?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are do interchangeable with a note: .prepare() will process signal handing for response sending but .start() will not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know.

resp_impl = self._start_pre_check(request)
if resp_impl is not None:
return resp_impl

return self._start(request)

@asyncio.coroutine
def prepare(self, request):
resp_impl = self._start_pre_check(request)
if resp_impl is not None:
return resp_impl

return self._start(request)

def _start(self, request):
self._req = request
keep_alive = self._keep_alive
if keep_alive is None:
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def handle(self, request):
file_size = st.st_size

resp.content_length = file_size
resp.start(request)
yield from resp.prepare(request)

with open(filepath, 'rb') as f:
yield from self._sendfile(request, resp, f, file_size)
Expand Down
34 changes: 25 additions & 9 deletions aiohttp/web_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ def __init__(self, *,
self._autoclose = autoclose
self._autoping = autoping

def start(self, request):
def prepare(self, request):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coroutine decorator missed here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

# make pre-check to don't hide it by do_handshake() exceptions
resp_impl = self._start_pre_check(request)
if resp_impl is not None:
return resp_impl

parser, protocol, writer = self._pre_start(request)
resp_impl = yield from super().prepare(request)
self._post_start(request, parser, protocol, writer)
return resp_impl

def _pre_start(self, request):
try:
status, headers, parser, writer, protocol = do_handshake(
request.method, request.headers, request.transport,
Expand All @@ -59,14 +65,24 @@ def start(self, request):
for k, v in headers:
self.headers[k] = v
self.force_close()
return parser, protocol, writer

resp_impl = super().start(request)

def _post_start(self, request, parser, protocol, writer):
self._reader = request._reader.set_parser(parser)
self._writer = writer
self._protocol = protocol
self._loop = request.app.loop

def start(self, request):
warnings.warn('use .prepare(request) instead', DeprecationWarning)
# make pre-check to don't hide it by do_handshake() exceptions
resp_impl = self._start_pre_check(request)
if resp_impl is not None:
return resp_impl

parser, protocol, writer = self._pre_start(request)
resp_impl = super().start(request)
self._post_start(request, parser, protocol, writer)
return resp_impl

def can_start(self, request):
Expand Down Expand Up @@ -98,22 +114,22 @@ def exception(self):

def ping(self, message='b'):
if self._writer is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')
if self._closed:
raise RuntimeError('websocket connection is closing')
self._writer.ping(message)

def pong(self, message='b'):
# unsolicited pong
if self._writer is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')
if self._closed:
raise RuntimeError('websocket connection is closing')
self._writer.pong(message)

def send_str(self, data):
if self._writer is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')
if self._closed:
raise RuntimeError('websocket connection is closing')
if not isinstance(data, str):
Expand All @@ -122,7 +138,7 @@ def send_str(self, data):

def send_bytes(self, data):
if self._writer is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')
if self._closed:
raise RuntimeError('websocket connection is closing')
if not isinstance(data, (bytes, bytearray, memoryview)):
Expand Down Expand Up @@ -151,7 +167,7 @@ def write_eof(self):
@asyncio.coroutine
def close(self, *, code=1000, message=b''):
if self._writer is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')

if not self._closed:
self._closed = True
Expand Down Expand Up @@ -190,7 +206,7 @@ def close(self, *, code=1000, message=b''):
@asyncio.coroutine
def receive(self):
if self._reader is None:
raise RuntimeError('Call .start() first')
raise RuntimeError('Call .prepare() first')
if self._waiting:
raise RuntimeError('Concurrent call to receive() is not allowed')

Expand Down
4 changes: 2 additions & 2 deletions examples/web_srv.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def intro(request):
binary = txt.encode('utf8')
resp = StreamResponse()
resp.content_length = len(binary)
resp.start(request)
yield from resp.prepare(request)
resp.write(binary)
return resp

Expand All @@ -36,7 +36,7 @@ def hello(request):
name = request.match_info.get('name', 'Anonymous')
answer = ('Hello, ' + name).encode('utf8')
resp.content_length = len(answer)
resp.start(request)
yield from resp.prepare(request)
resp.write(answer)
yield from resp.write_eof()
return resp
Expand Down
2 changes: 1 addition & 1 deletion examples/web_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def wshandler(request):
with open(WS_FILE, 'rb') as fp:
return Response(body=fp.read(), content_type='text/html')

resp.start(request)
yield from resp.prepare(request)
print('Someone joined.')
for ws in request.app['sockets']:
ws.send_str('Someone joined')
Expand Down
2 changes: 1 addition & 1 deletion tests/autobahn/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def wshandler(request):
if not ok:
return web.HTTPBadRequest()

ws.start(request)
yield from ws.prepare(request)

while True:
msg = yield from ws.receive()
Expand Down
6 changes: 3 additions & 3 deletions tests/test_web_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_all_http_exceptions_exported(self):
def test_HTTPOk(self):
req = self.make_request()
resp = web.HTTPOk()
resp.start(req)
self.loop.run_until_complete(resp.prepare(req))
self.loop.run_until_complete(resp.write_eof())
txt = self.buf.decode('utf8')
self.assertRegex(txt, ('HTTP/1.1 200 OK\r\n'
Expand Down Expand Up @@ -85,7 +85,7 @@ def test_HTTPFound(self):
resp = web.HTTPFound(location='/redirect')
self.assertEqual('/redirect', resp.location)
self.assertEqual('/redirect', resp.headers['location'])
resp.start(req)
self.loop.run_until_complete(resp.prepare(req))
self.loop.run_until_complete(resp.write_eof())
txt = self.buf.decode('utf8')
self.assertRegex(txt, ('HTTP/1.1 302 Found\r\n'
Expand All @@ -110,7 +110,7 @@ def test_HTTPMethodNotAllowed(self):
self.assertEqual('GET', resp.method)
self.assertEqual(['POST', 'PUT'], resp.allowed_methods)
self.assertEqual('POST,PUT', resp.headers['allow'])
resp.start(req)
self.loop.run_until_complete(resp.prepare(req))
self.loop.run_until_complete(resp.write_eof())
txt = self.buf.decode('utf8')
self.assertRegex(txt, ('HTTP/1.1 405 Method Not Allowed\r\n'
Expand Down
2 changes: 1 addition & 1 deletion tests/test_web_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ def test_stream_response_multiple_chunks(self):
def handler(request):
resp = web.StreamResponse()
resp.enable_chunked_encoding()
resp.start(request)
yield from resp.prepare(request)
resp.write(b'x')
resp.write(b'y')
resp.write(b'z')
Expand Down
Loading