This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author MultiSosnooley
Recipients MultiSosnooley, asvetlov, yselivanov
Date 2019-02-24.00:22:05
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1550967725.88.0.520289067216.issue36098@roundup.psfhosted.org>
In-reply-to
Content
Recently, some awesome contributors add support for implicit ssl mode for aioftp. But this produced some issues and one of them is not relevant to aioftp, but to asyncio. Here is link https://repl.it/@multisosnooley/asyncio-ssl-connection-with-slow-retreiving to reproduce. This code mimics one test of aioftp: filesystem slower, than socket write. Reduced code to reproduce use sleep for this purpose. So we have proper run without ssl (you can test this by removing ssl argument in server and client instantiation) and «buggy» in case of ssl. After some digging in I realised, that someone calls connection_lost of ssl protocol before we read all data from transport. Data sent by server, but client have (looks like 64k) buffer and since there is no transport read fails. Also, I can say (with help of wireshark) that in case of non-ssl connection, tcp FIN initiated by server (as it should be), but in case of ssl — FIN sent by client.

Direct code to reproduce
```
import ssl
import asyncio

import trustme


HOST = "127.0.0.1"
PORT = 8021

ca = trustme.CA()
server_cert = ca.issue_server_cert(HOST)

ssl_server = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
server_cert.configure_cert(ssl_server)

ssl_client = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ca.configure_trust(ssl_client)


async def handler(reader, writer):
    writer.write(b"0" * 4 * 100 * 1024)
    await writer.drain()
    writer.close()
    await asyncio.sleep(1)
    print("handler done")


async def client():
    # reader, writer = await asyncio.open_connection(HOST, PORT)
    reader, writer = await asyncio.open_connection(HOST, PORT, ssl=ssl_client)
    count = 0
    while True:
        data = await reader.read(8192)
        count += len(data)
        print(f"received {len(data)}, total {count}")
        if not data:
            break
        await asyncio.sleep(0.001)
    writer.close()


loop = asyncio.get_event_loop()
# start = asyncio.start_server(handler, HOST, PORT)
start = asyncio.start_server(handler, HOST, PORT, ssl=ssl_server)
server = loop.run_until_complete(start)
loop.run_until_complete(client())
server.close()
loop.run_until_complete(server.wait_closed())
```

Output:
```
received 8192, total 8192
received 8192, total 16384
received 8192, total 24576
received 8192, total 32768
received 8192, total 40960
received 8192, total 49152
received 8192, total 57344
received 8192, total 65536
received 8192, total 73728
received 8192, total 81920
received 8192, total 90112
received 8192, total 98304
received 8192, total 106496
received 8192, total 114688
received 8192, total 122880
received 8192, total 131072
received 8192, total 139264
received 8192, total 147456
received 8192, total 155648
received 8192, total 163840
received 8192, total 172032
received 8192, total 180224
received 8192, total 188416
received 8192, total 196608
received 8192, total 204800
received 8192, total 212992
received 8192, total 221184
received 8192, total 229376
received 8192, total 237568
received 8192, total 245760
received 8192, total 253952
received 8192, total 262144
received 8192, total 270336
received 8192, total 278528
received 8192, total 286720
received 8192, total 294912
received 8192, total 303104
received 8192, total 311296
received 8192, total 319488
received 8192, total 327680
received 8192, total 335872
Traceback (most recent call last):
  File "slow-data-test.py", line 46, in <module>
    loop.run_until_complete(client())
  File "/home/poh/.pyenv/versions/3.6.7/lib/python3.6/asyncio/base_events.py", line 473, in run_until_complete
    return future.result()
  File "slow-data-test.py", line 33, in client
    data = await reader.read(8192)
  File "/home/poh/.pyenv/versions/3.6.7/lib/python3.6/asyncio/streams.py", line 640, in read
    self._maybe_resume_transport()
  File "/home/poh/.pyenv/versions/3.6.7/lib/python3.6/asyncio/streams.py", line 408, in _maybe_resume_transport
    self._transport.resume_reading()
  File "/home/poh/.pyenv/versions/3.6.7/lib/python3.6/asyncio/sslproto.py", line 351, in resume_reading
    self._ssl_protocol._transport.resume_reading()
AttributeError: 'NoneType' object has no attribute 'resume_reading'
```
History
Date User Action Args
2019-02-24 00:22:05MultiSosnooleysetrecipients: + MultiSosnooley, asvetlov, yselivanov
2019-02-24 00:22:05MultiSosnooleysetmessageid: <1550967725.88.0.520289067216.issue36098@roundup.psfhosted.org>
2019-02-24 00:22:05MultiSosnooleylinkissue36098 messages
2019-02-24 00:22:05MultiSosnooleycreate