[issue23333] asyncio: call protocol.connection_lost() when the creation of transport failed
STINNER Victor added the comment: The call to loop.add_reader() should maybe be scheduled after the call to connection_made()? To ensure that protocol methods (feed_data) are not called before connection_made() has been called. Fixed by: --- changeset: 94360:1b35bef31bf8 branch: 3.4 tag: tip user:Victor Stinner victor.stin...@gmail.com date:Thu Jan 29 00:36:51 2015 +0100 files: Lib/asyncio/selector_events.py Lib/test/test_asyncio/test_selector_events.py description: asyncio: Fix _SelectorSocketTransport constructor Only start reading when connection_made() has been called: protocol.data_received() must not be called before protocol.connection_made(). --- Other fix related to this issue: --- changeset: 94358:1da90ebae442 branch: 3.4 parent: 94355:263344bb2107 user:Victor Stinner victor.stin...@gmail.com date:Thu Jan 29 00:35:56 2015 +0100 files: Lib/asyncio/sslproto.py Lib/test/test_asyncio/test_sslproto.py description: asyncio: Fix SSLProtocol.eof_received() Wake-up the waiter if it is not done yet. --- -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue2 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23333] asyncio: call protocol.connection_lost() when the creation of transport failed
STINNER Victor added the comment: Oh, accept_error.patch causes issues with the new SSL implementation. SSLProtocol.feed_data() is called before SSLProtocol.connection_made() is called. _SelectorSocketTransport constructor calls loop.add_reader() immediatly, but it only schedules a call to protocol.connection_made() with loop.call_soon(). The call to loop.add_reader() should maybe be scheduled after the call to connection_made()? To ensure that protocol methods (feed_data) are not called before connection_made() has been called. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue2 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23333] asyncio: call protocol.connection_lost() when the creation of transport failed
New submission from STINNER Victor: While working on the issue #23243 (asyncio: emit ResourceWarning warnings if transports/event loops are not explicitly closed), I saw that SelectorEventLoop._accept_connection() currently ignores errors on the creation of a transport. When a server gets an incoming connection: it calls sock.accept(), creates a protocol, and then create the transport. It doesn't wait until the connection_made() of the protocol is called (until the transport was successfully created). For example, for a SSL server, the client may decide to close the connection because it doesn't trust the server certificate. In this case, the SSL handshake fails at server side. Currently, the user of the asyncio API cannot decide how to handle this failure. I propose to call the connection_lost() method of the protocol with the exception, even if the connection_made() method of the protocol was not called (and will never be called). Attached patch implements this idea. It's a change in the undocumented state machine of protocols. Before, it was not possible to switch directly to connection_lost(): there is even an assertion which ensures that it never occurs in some unit tests. A server may log the connection failure, blacklist temporarely the client IP, etc. Problem: Since the protocol doesn't know the transport yet, it doesn't have access to the socket, and so cannot retrieve the IP address of the client. Maybe a new method should be added to protocols to handle this case? How do other event loops (Twisted, eventlet, Tornado, etc.) handle failures on incoming connection? -- components: asyncio files: accept_error.patch keywords: patch messages: 234856 nosy: gvanrossum, haypo, yselivanov priority: normal severity: normal status: open title: asyncio: call protocol.connection_lost() when the creation of transport failed versions: Python 3.4, Python 3.5 Added file: http://bugs.python.org/file37884/accept_error.patch ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue2 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23333] asyncio: call protocol.connection_lost() when the creation of transport failed
Antoine Pitrou added the comment: IMO, connection_lost() should never be called if connection_made() wasn't called. That's a breach of the API contract. (at one point, I suggested a connection_failed() for that purpose, but it was shut down - it was in relationship to the idea of a reconnecting client, but can still be more broadly useful) -- nosy: +pitrou ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue2 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue23333] asyncio: call protocol.connection_lost() when the creation of transport failed
STINNER Victor added the comment: FYI I opened a thread about this issue on the Tulip mailing list. Antoine Pitrou added the comment: IMO, connection_lost() should never be called if connection_made() wasn't called. That's a breach of the API contract. Yes, I agree. (at one point, I suggested a connection_failed() for that purpose, but it was shut down - it was in relationship to the idea of a reconnecting client, but can still be more broadly useful) I like the connection_failed name. We may call protocol.connection_failed(transport), so the protocol gets access to the socket and so to the IP addres. -- ___ Python tracker rep...@bugs.python.org http://bugs.python.org/issue2 ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com