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
This commit is contained in:
Yury Selivanov 2018-05-28 14:31:28 -04:00 committed by GitHub
parent e549c4be5f
commit dbf102271f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 382 additions and 69 deletions

View file

@ -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)