-
-
Notifications
You must be signed in to change notification settings - Fork 29.4k
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
bpo-23749: Implement loop.start_tls() #5039
Conversation
@@ -305,6 +305,16 @@ def set_default_executor(self, executor): | |||
""" | |||
raise NotImplementedError | |||
|
|||
async def start_tls(self, transport, protocol, sslcontext, *, | |||
server_side=False, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add server_hostname
parameter maybe?
At least create_connection
has it, checking hostname match increases security.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, server_hostname
should be added. Or perhaps a bunch of kwargs
to allow passing arbitrary arguments to wrap_socket
or wrap_bio
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, will add it.
Or perhaps a bunch of kwargs to allow passing arbitrary arguments to wrap_socket or wrap_bio.
We don't do that in loop.create_connection
or in loop.create_server
, we explicitly pass params there. Most of the stuff can be configured through the SSLContext
anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I guess that could be deferred to another PR. However, the ssl
module may add some other parameters along the way, and it would be nicer to inherit them automatically. For example, Python 3.6 got the session
parameter: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Can you make a PR after this one lands?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarification: asyncio doesn't use ssl.wrap_socket
since Python 3.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it uses ssl.wrap_bio
which accepts similar arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good except minor note
Lib/asyncio/base_events.py
Outdated
f'transport {self!r} is not supported by start_tls()') | ||
|
||
if transport.get_write_buffer_size(): | ||
if transport._buffer_drained_fut is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to rely on an implementation detail here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Transports are intimately tied to event loops and are aware of each other private details. Another event loop, say uvloop, can't support asyncio Transport
classes, and vice versa.
Currently, transports don't have APIs to notify the loop when their write buffers are drained. We probably need to design such a public API, but that's out of the scope of this PR.
That said, I think I'll add a private base class to share some functionality between Proactor and Selector transport classes. That will also make the code a bit prettier.
Lib/asyncio/base_events.py
Outdated
|
||
waiter = self.create_future() | ||
app_transport = self._make_ssl_transport( | ||
transport._sock, protocol, sslcontext, waiter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps use transport.get_extra_info('socket')
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since asyncio loop doesn't work uvloop transport (it's true for any loop implementation) using private attributes is perfectly fine from my perspective.
Lib/asyncio/base_events.py
Outdated
transport._sock, protocol, sslcontext, waiter, | ||
server_side=server_side, | ||
ssl_handshake_timeout=ssl_handshake_timeout, | ||
server=transport._server, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question.
import threading | ||
|
||
|
||
class FunctionalTestCaseMixin: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add docstrings in classes and important methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a private unittest helper class in Lib/test/test_asyncio/
... I copied it from uvloop and I'm still in the process of refactoring it and adapting it to asyncio/Python needs. So I'll add docstrings later.
c495ece
to
64a4469
Compare
So after some investigation why What I decided to do instead is to simply instantiate The new approach is way safer than the previous one:
|
https://bugs.python.org/issue23749