Skip to content

uasynio.stream.Stream.readline fails when using SSL #9015

Description

@fruch

I was trying to adapt one of the http clients (urequests/uaiohttp) to be able to use https

base on the basic example of ussl.warp_socket (and few other examples of people trying it out)
and I was hitting this failure when trying to use Stream.readline(), while it's working o.k. when using a non ssl wrapped socket

I've tested it on the unix micropython, both on 1.19 and 1.18

❯ docker run -it -w /home  -v `pwd`/lib:/root/.micropython/lib -v `pwd`:/home micropython/unix:v1.19 micropython-dev net_example.py
Address infos: [(2, 1, 6, None, bytearray(b'\x02\x00\x01\xbbh\xed\x89\xd3\x00\x00\x00\x00\x00\x00\x00\x00')), (2, 2, 17, None, bytearray(b'\x02\x00\x01\xbbh\xed\x89\xd3\x00\x00\x00\x00\x00\x00\x00\x00')), (2, 3, 0, None, bytearray(b'\x02\x00\x01\xbbh\xed\x89\xd3\x00\x00\x00\x00\x00\x00\x00\x00'))]
Connect address: bytearray(b'\x02\x00\x01\xbbh\xed\x89\xd3\x00\x00\x00\x00\x00\x00\x00\x00')
Traceback (most recent call last):
  File "net_example.py", line 53, in <module>
  File "uasyncio/core.py", line 1, in run_until_complete
  File "uasyncio/core.py", line 1, in run_until_complete
  File "uasyncio/core.py", line 1, in run_until_complete
  File "net_example.py", line 46, in main
  File "uasyncio/stream.py", line 1, in readline
TypeError: unsupported types for __iadd__: 'bytes', 'NoneType'

here's the example that reproduce it:

try:
    import usocket as _socket
except:
    import _socket
try:
    import ussl as ssl
except:
    import ssl

# https://github.com/micropython/micropython/blob/master/examples/network/http_client_ssl.py
# https://freewavesamples.com/files/Ensoniq-ZR-76-08-Dope-92.wav
# http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples/AFsp/M1F1-Alaw-AFsp.wav

import uasyncio as asyncio

from uasyncio.stream import Stream
from uasyncio import core


async def main(https=True):
    s = _socket.socket()

    if https:
        ai = _socket.getaddrinfo("freewavesamples.com", 443)
    else:
        ai = _socket.getaddrinfo("www-mmsp.ece.mcgill.ca", 80)
    print("Address infos:", ai)
    addr = ai[2][-1]

    print("Connect address:", addr)
    s.connect(addr)

    if https:
        s = ssl.wrap_socket(s)
    s.setblocking(False)
    yield core._io_queue.queue_write(s)
    ss = Stream(s)

    if https:
        ss.write(b"GET /files/Ensoniq-ZR-76-08-Dope-92.wav HTTP/1.0\r\nHost: freewavesamples.com\r\n\r\n")
    else:
        ss.write(b"GET /Documents/AudioFormats/WAVE/Samples/AFsp/M1F1-Alaw-AFsp.wav HTTP/1.0\r\nHost: www-mmsp.ece.mcgill.ca\r\n\r\n")

    await ss.drain()
    # print(await ss.read(4096)) # this works both on http/https
    print(await ss.readline()) # readline works only on http
    print(await ss.readline())

    ss.close()


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

Activity

  1. fruch commented on Aug 4, 2022

    @fruch
    Author

    seem like my problem is solves with adding if not l2: continue into readline implementations

    async def readline(self):
            l = b""
            while True:
                yield core._io_queue.queue_read(self.s)
                l2 = self.s.readline()  # may do multiple reads but won't block
                if not l2: continue
                l += l2
                if not l2 or l[-1] == 10:  # \n (check l in case l2 is str)
                    return l
    
    Stream.readline = readline

    on more observation is that if was enough to read once from the socket, and then readline was working o.k.

    So I'm guessing the SSL handshake leave something unread in the socket buffer, otherwise I have no clue (didn't looking into the socket readline implementation.

    Anyhow I think handling None in Stream.readline is missing, regardless of what casues socket.readline to return None

  2. added
    extmodRelates to extmod/ directory in source
    on Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugextmodRelates to extmod/ directory in source

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions