async def request_blob(loop: asyncio.BaseEventLoop, blob: 'AbstractBlob', address: str, tcp_port: int, peer_connect_timeout: float, blob_download_timeout: float, connected_transport: asyncio.Transport = None, connection_id: int = 0, connection_manager: typing.Optional['ConnectionManager'] = None)\ -> typing.Tuple[int, typing.Optional[asyncio.Transport]]: """ Returns [<downloaded blob>, <keep connection>] """ protocol = BlobExchangeClientProtocol( loop, blob_download_timeout, connection_manager ) if connected_transport and not connected_transport.is_closing(): connected_transport.set_protocol(protocol) protocol.transport = connected_transport log.debug("reusing connection for %s:%d", address, tcp_port) else: connected_transport = None try: if not connected_transport: await asyncio.wait_for(loop.create_connection(lambda: protocol, address, tcp_port), peer_connect_timeout, loop=loop) if blob.get_is_verified() or not blob.is_writeable(): # file exists but not verified means someone is writing right now, give it time, come back later return 0, connected_transport return await protocol.download_blob(blob) except (asyncio.TimeoutError, ConnectionRefusedError, ConnectionAbortedError, OSError): return 0, None
async def start_tls( loop: asyncio.AbstractEventLoop, transport: asyncio.Transport, protocol: asyncio.Protocol, sslcontext: ssl.SSLContext, server_side: bool = False, server_hostname: Optional[str] = None, ssl_handshake_timeout: Optional[Union[float, int]] = None, ) -> asyncio.Transport: # We use hasattr here, as uvloop also supports start_tls. if hasattr(loop, "start_tls"): return await loop.start_tls( # type: ignore transport, protocol, sslcontext, server_side=server_side, server_hostname=server_hostname, ssl_handshake_timeout=ssl_handshake_timeout, ) waiter = loop.create_future() ssl_protocol = SSLProtocol(loop, protocol, sslcontext, waiter, server_side, server_hostname) # Pause early so that "ssl_protocol.data_received()" doesn't # have a chance to get called before "ssl_protocol.connection_made()". transport.pause_reading() # Use set_protocol if we can if hasattr(transport, "set_protocol"): transport.set_protocol(ssl_protocol) # type: ignore else: transport._protocol = ssl_protocol # type: ignore conmade_cb = loop.call_soon(ssl_protocol.connection_made, transport) resume_cb = loop.call_soon(transport.resume_reading) try: await asyncio.wait_for(waiter, timeout=ssl_handshake_timeout) except Exception: transport.close() conmade_cb.cancel() resume_cb.cancel() raise return ssl_protocol._app_transport