8000 extmod/uasyncio: Fix readline if returns None. · micropython/micropython@16cd048 · GitHub
[go: up one dir, main page]

Skip to content

Commit 16cd048

Browse files
committed
extmod/uasyncio: Fix readline if returns None.
Reading from a stream ssl socket too soon will return `None` so this avoids adding the bytes buffer with None raising `TypeError`. Signed-off-by: Carlos Gil <carlosgilglez@gmail.com>
1 parent 56f7178 commit 16cd048

File tree

5 files changed

+106
-8
lines changed

5 files changed

+106
-8
lines changed

extmod/asyncio/stream.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# MIT license; Copyright (c) 2019-2020 Damien P. George
33

44
from . import core
5+
import sys
56

67
try:
78
import ssl as _ssl
@@ -91,12 +92,18 @@ def readline(self):
9192
if hasattr(self.s, "ssl_pending"):
9293
if self.s.ssl_pending():
9394
l2 = self.s.readline()
94-
l += l2
95+
if l2:
96+
l += l2
97+
if l2 is None:
98+
continue
9599
if not l2 or l[-1] == 10:
96100
return l
97101
yield core._io_queue.queue_read(self.s)
98102
l2 = self.s.readline() # may do multiple reads but won't block
99-
l += l2
103+
if l2:
104+
l += l2
105+
if l2 is None:
106+
continue
100107
if not l2 or l[-1] == 10: # \n (check l in case l2 is str)
101108
return l
102109

@@ -204,10 +211,9 @@ async def _serve(self, s, cb, ssl):
204211
s2.setblocking(True)
205212
try:
206213
s2 = ssl.wrap_socket(s2, server_side=True)
207-
except OSError as e:
208-
print(e)
214+
except Exception as e:
215+
sys.print_exception(e)
209216
s2.close()
210-
ssl._reload_ctx = True
211217
continue
212218
s2.setblocking(False)
213219
s2s = Stream(s2, {"peername": addr})

extmod/ssl/ssl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
PROTOCOL_TLS_CLIENT = const(0)
66
PROTOCOL_TLS_SERVER = const(1)
77

8+
89
# backwards compatibility even after C code is deprecated
910
def wrap_socket(
1011
sock,
@@ -150,7 +151,6 @@ def wrap_socket(
150151
do_handshake_on_connect=True,
151152
server_hostname=None,
152153
):
153-
154154
if self.check_hostname and server_hostname is None:
155155
raise ValueError("check_hostname requires server_hostname")
156156
# to be substituted by e.g. _ussl._context_wrap_socket in modussl_mbedtls.c ?:

tests/multi_net/ssl_context_rsa.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@
128128
b"8b17a330a306a6fbcf51ba83563aed85a4f886fff1a22423748d83798c"
129129
)
130130

131+
131132
# Server
132133
def instance0():
133-
134134
multitest.globals(IP=multitest.get_network_ip())
135135
s = socket.socket()
136136
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

tests/net_inet/test_ssl_context_client.py

Lines changed: 0 additions & 1 deletion
57AE
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060

6161

6262
def main(use_stream=True):
63-
6463
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
6564

6665
# context.verify_mode = ssl.CERT_REQUIRED # enabled by default with
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Test simple HTTPS request with uasyncio.open_connection()
2+
3+
try:
4+
import ubinascii as binascii
5+
import uasyncio as asyncio
< B41A /code>
6+
except ImportError:
7+
try:
8+
import asyncio
9+
import binascii
10+
except ImportError:
11+
print("SKIP")
12+
raise SystemExit
13+
14+
import ssl
15+
16+
17+
# This certificate was obtained from micropython.org using openssl:
18+
# $ openssl s_client -showcerts -connect micropython.org:443 </dev/null 2>/dev/null
19+
# The certificate is from Let's Encrypt:
20+
# 1 s:/C=US/O=Let's Encrypt/CN=R3
21+
# i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
22+
# Validity
23+
# Not Before: Sep 4 00:00:00 2020 GMT
24+
# Not After : Sep 15 16:00:00 2025 GMT
25+
# Copy PEM content to a file (certmpy.pem) and convert to DER e.g.
26+
# $ openssl x509 -in certmpy.pem -out certmpy.der -outform DER
27+
# Then convert to hex format, eg using binascii.hexlify(data).
28+
29+
ca_cert_chain = binascii.unhexlify(
30+
b"30820516308202fea003020102021100912b084acf0c18a753f6d62e25a75f5a300d06092a864886"
31+
b"f70d01010b0500304f310b300906035504061302555331293027060355040a1320496e7465726e65"
32+
b"742053656375726974792052657365617263682047726f7570311530130603550403130c49535247"
33+
b"20526f6f74205831301e170d3230303930343030303030305a170d3235303931353136303030305a"
34+
b"3032310b300906035504061302555331163014060355040a130d4c6574277320456e637279707431"
35+
b"0b300906035504031302523330820122300d06092a864886f70d01010105000382010f003082010a"
36+
b"0282010100bb021528ccf6a094d30f12ec8d5592c3f882f199a67a4288a75d26aab52bb9c54cb1af"
37+
b"8e6bf975c8a3d70f4794145535578c9ea8a23919f5823c42a94e6ef53bc32edb8dc0b05cf35938e7"
38+
b"edcf69f05a0b1bbec094242587fa3771b313e71cace19befdbe43b45524596a9c153ce34c852eeb5"
39+
b"aeed8fde6070e2a554abb66d0e97a540346b2bd3bc66eb66347cfa6b8b8f572999f830175dba726f"
40+
b"fb81c5add286583d17c7e709bbf12bf786dcc1da715dd446e3ccad25c188bc60677566b3f118f7a2"
41+
b"5ce653ff3a88b647a5ff1318ea9809773f9d53f9cf01e5f5a6701714af63a4ff99b3939ddc53a706"
42+
b"fe48851da169ae2575bb13cc5203f5ed51a18bdb150203010001a382010830820104300e0603551d"
43+
b"0f0101ff040403020186301d0603551d250416301406082b0601050507030206082b060105050703"
44+
b"0130120603551d130101ff040830060101ff020100301d0603551d0e04160414142eb317b75856cb"
45+
b"ae500940e61faf9d8b14c2c6301f0603551d2304183016801479b459e67bb6e5e40173800888c81a"
46+
b"58f6e99b6e303206082b0601050507010104263024302206082b060105050730028616687474703a"
47+
b"2f2f78312e692e6c656e63722e6f72672f30270603551d1f0420301e301ca01aa018861668747470"
48+
b"3a2f2f78312e632e6c656e63722e6f72672f30220603551d20041b30193008060667810c01020130"
49+
b"0d060b2b0601040182df13010101300d06092a864886f70d01010b0500038202010085ca4e473ea3"
50+
b"f7854485bcd56778b29863ad754d1e963d336572542d81a0eac3edf820bf5fccb77000b76e3bf65e"
51+
b"94dee4209fa6ef8bb203e7a2b5163c91ceb4ed3902e77c258a47e6656e3f46f4d9f0ce942bee54ce"
52+
b"12bc8c274bb8c1982fa2afcd71914a08b7c8b8237b042d08f908573e83d904330a472178098227c3"
53+
b"2ac89bb9ce5cf264c8c0be79c04f8e6d440c5e92bb2ef78b10e1e81d4429db5920ed63b921f81226"
54+
b"949357a01d6504c10a22ae100d4397a1181f7ee0e08637b55ab1bd30bf876e2b2aff214e1b05c3f5"
55+
b"1897f05eacc3a5b86af02ebc3b33b9ee4bdeccfce4af840b863fc0554336f668e136176a8e99d1ff"
56+
b"a540a734b7c0d063393539756ef2ba76c89302e9a94b6c17ce0c02d9bd81fb9fb768d40665b3823d"
57+
b"7753f88e7903ad0a3107752a43d8559772c4290ef7c45d4ec8ae468430d7f2855f18a179bbe75e70"
58+
b"8b07e18693c3b98fdc6171252aafdfed255052688b92dce5d6b5e3da7dd0876c842131ae82f5fbb9"
59+
b"abc889173de14ce5380ef6bd2bbd968114ebd5db3d20a77e59d3e2f858f95bb848cdfe5c4f1629fe"
60+
b"1e5523afc811b08dea7c9390172ffdaca20947463ff0e9b0b7ff284d6832d6675e1e69a393b8f59d"
61+
b"8b2f0bd25243a66f3257654d3281df3853855d7e5d6629eab8dde495b5cdb5561242cdc44ec62538"
62+
b"44506decce005518fee94964d44eca979cb45bc073a8abb847c2"
63+
)
64+
65+
client_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
66+
client_ctx.load_verify_locations(cadata=ca_cert_chain)
67+
client_ctx.load_default_certs()
68+
69+
70+
async def http_get(url, port, sslctx):
71+
reader, writer = await asyncio.open_connection(url, port, ssl=sslctx)
72+
73+
print("write GET")
74+
writer.write(b"GET / HTTP/1.0\r\n\r\n")
75+
await writer.drain()
76+
77+
print("read response")
78+
# await asyncio.sleep(1)
79+
while True:
80+
data = await reader.readline()
81+
# avoid printing datetime which makes the test fail
82+
if b"GMT" not in data:
83+
print("read:", data)
84+
if not data:
85+
break
86+
87+
print("close")
88+
writer.close()
89+
await writer.wait_closed()
90+
print("done")
91+
92+
93+
asyncio.run(http_get("micropython.org", 443, client_ctx))

0 commit comments

Comments
 (0)
0