summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/sslproto.py
diff options
context:
space:
mode:
authorYury Selivanov <yury@magic.io>2018-05-28 18:31:28 (GMT)
committerGitHub <noreply@github.com>2018-05-28 18:31:28 (GMT)
commitdbf102271fcc316f353c7e0a283811b661d128f2 (patch)
tree8807a0305490616dc3b480fae5e50e98c80b4fa8 /Lib/asyncio/sslproto.py
parente549c4be5fb010f5faf12236af8faa720a1429be (diff)
downloadcpython-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.py32
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)