diff options
author | Yury Selivanov <yury@magic.io> | 2018-05-28 18:31:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-28 18:31:28 (GMT) |
commit | dbf102271fcc316f353c7e0a283811b661d128f2 (patch) | |
tree | 8807a0305490616dc3b480fae5e50e98c80b4fa8 /Lib/asyncio/sslproto.py | |
parent | e549c4be5fb010f5faf12236af8faa720a1429be (diff) | |
download | cpython-dbf102271fcc316f353c7e0a283811b661d128f2.zip cpython-dbf102271fcc316f353c7e0a283811b661d128f2.tar.gz cpython-dbf102271fcc316f353c7e0a283811b661d128f2.tar.bz2 |
bpo-33654: Support BufferedProtocol in set_protocol() and start_tls() (GH-7130)
In this commit:
* Support BufferedProtocol in set_protocol() and start_tls()
* Fix proactor to cancel readers reliably
* Update tests to be compatible with OpenSSL 1.1.1
* Clarify BufferedProtocol docs
* Bump TLS tests timeouts to 60 seconds; eliminate possible race from start_serving
* Rewrite test_start_tls_server_1
Diffstat (limited to 'Lib/asyncio/sslproto.py')
-rw-r--r-- | Lib/asyncio/sslproto.py | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 2bbf134..2bfa45d 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -441,6 +441,8 @@ class SSLProtocol(protocols.Protocol): self._waiter = waiter self._loop = loop self._app_protocol = app_protocol + self._app_protocol_is_buffer = \ + isinstance(app_protocol, protocols.BufferedProtocol) self._app_transport = _SSLProtocolTransport(self._loop, self) # _SSLPipe instance (None until the connection is made) self._sslpipe = None @@ -522,7 +524,16 @@ class SSLProtocol(protocols.Protocol): for chunk in appdata: if chunk: - self._app_protocol.data_received(chunk) + try: + if self._app_protocol_is_buffer: + _feed_data_to_bufferred_proto( + self._app_protocol, chunk) + else: + self._app_protocol.data_received(chunk) + except Exception as ex: + self._fatal_error( + ex, 'application protocol failed to receive SSL data') + return else: self._start_shutdown() break @@ -709,3 +720,22 @@ class SSLProtocol(protocols.Protocol): self._transport.abort() finally: self._finalize() + + +def _feed_data_to_bufferred_proto(proto, data): + data_len = len(data) + while data_len: + buf = proto.get_buffer(data_len) + buf_len = len(buf) + if not buf_len: + raise RuntimeError('get_buffer() returned an empty buffer') + + if buf_len >= data_len: + buf[:data_len] = data + proto.buffer_updated(data_len) + return + else: + buf[:buf_len] = data[:buf_len] + proto.buffer_updated(buf_len) + data = data[buf_len:] + data_len = len(data) |