Skip to content

Commit f41a0c1

Browse files
websockets: worse
1 parent 25a7aa3 commit f41a0c1

File tree

1 file changed

+69
-49
lines changed

1 file changed

+69
-49
lines changed

draft_code/modwebsocket_test.py

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import ssl
33
import ubinascii
44
from websocket import websocket
5+
import time
56

67
# Connect to Wi-Fi (disabled as per your code)
78
if False:
@@ -13,8 +14,15 @@
1314
print('Connected:', wlan.ifconfig())
1415

1516
# Resolve hostname
17+
# Option 1: echo.websocket.events (unreliable)
1618
host = 'echo.websocket.events'
1719
port = 443
20+
handshake_path = '/'
21+
# Option 2: ws.postman-echo.com (recommended for testing)
22+
# host = 'ws.postman-echo.com'
23+
# port = 443
24+
# handshake_path = '/raw'
25+
1826
try:
1927
addr_info = socket.getaddrinfo(host, port)[0][-1]
2028
print('Resolved address:', addr_info)
@@ -41,17 +49,21 @@
4149
sock.close()
4250
raise
4351

52+
# Set socket to non-blocking
53+
ssl_sock.setblocking(False)
54+
print('Socket set to non-blocking')
55+
4456
# Perform WebSocket handshake
4557
key = ubinascii.b2a_base64(b'random_bytes_here').strip()
4658
handshake = (
47-
'GET / HTTP/1.1\r\n'
59+
'GET {} HTTP/1.1\r\n'
4860
'Host: {}\r\n'
4961
'Upgrade: websocket\r\n'
5062
'Connection: Upgrade\r\n'
5163
'Sec-WebSocket-Key: {}\r\n'
5264
'Sec-WebSocket-Version: 13\r\n'
5365
'\r\n'
54-
).format(host, key.decode())
66+
).format(handshake_path, host, key.decode())
5567

5668
# Send handshake request
5769
try:
@@ -63,12 +75,10 @@
6375
ssl_sock.close()
6476
raise
6577

66-
# Read HTTP response until \r\n\r\n
78+
# Read HTTP response until \r\n\r\n (minimize reading)
6779
response_bytes = bytearray()
68-
max_read = 1024 # Maximum bytes to read
69-
read_timeout = 2 # Reduced timeout (seconds)
70-
import time
71-
80+
max_read = 1024
81+
read_timeout = 2
7282
start_time = time.time()
7383
while len(response_bytes) < max_read:
7484
try:
@@ -79,9 +89,29 @@
7989
print('Received chunk, length:', len(chunk), 'bytes:', chunk)
8090
response_bytes.extend(chunk)
8191
print('Total bytes received:', len(response_bytes))
82-
# Check for end of HTTP headers (\r\n\r\n)
8392
if b'\r\n\r\n' in response_bytes:
8493
print('End of HTTP headers detected')
94+
# Decode and verify HTTP response immediately
95+
http_end = response_bytes.find(b'\r\n\r\n') + 4
96+
if http_end < 4:
97+
ssl_sock.close()
98+
raise Exception('Invalid HTTP response: no headers found')
99+
http_response_bytes = response_bytes[:http_end]
100+
try:
101+
response = http_response_bytes.decode('utf-8')
102+
print('Decoded HTTP response:', response)
103+
except UnicodeError as e:
104+
print('UnicodeError during decode:', e)
105+
printable = ''.join(c if 32 <= ord(c) < 127 else '.' for c in http_response_bytes.decode('latin-1'))
106+
print('Printable characters:', printable)
107+
ssl_sock.close()
108+
raise Exception('Failed to decode HTTP response')
109+
if '101 Switching Protocols' not in response:
110+
print('Handshake response:', response)
111+
ssl_sock.close()
112+
raise Exception('Handshake failed')
113+
# Stop reading to leave WebSocket frame in socket buffer
114+
print('Stopping read to preserve WebSocket frame')
85115
break
86116
except Exception as e:
87117
print('Error reading chunk:', e)
@@ -90,51 +120,41 @@
90120
print('Read timeout reached')
91121
break
92122

93-
# Inspect raw bytes
94-
print('Raw response bytes:', response_bytes)
95-
print('Raw response hex:', response_bytes.hex())
96-
97-
# Split HTTP response from any subsequent data
98-
http_end = response_bytes.find(b'\r\n\r\n') + 4
99-
if http_end < 4:
100-
ssl_sock.close()
101-
raise Exception('Invalid HTTP response: no headers found')
102-
http_response_bytes = response_bytes[:http_end]
103-
extra_bytes = response_bytes[http_end:] if http_end < len(response_bytes) else b''
104-
print('HTTP response bytes:', http_response_bytes)
105-
print('Extra bytes (if any):', extra_bytes)
106-
107-
# Decode HTTP response
123+
# Create WebSocket object
108124
try:
109-
response = http_response_bytes.decode('utf-8')
110-
print('Decoded HTTP response:', response)
111-
except UnicodeError as e:
112-
print('UnicodeError during decode:', e)
113-
# Dump printable characters as fallback
114-
printable = ''.join(c if 32 <= ord(c) < 127 else '.' for c in http_response_bytes.decode('latin-1'))
115-
print('Printable characters:', printable)
116-
ssl_sock.close()
117-
raise Exception('Failed to decode HTTP response')
118-
119-
# Check for valid WebSocket handshake
120-
if '101 Switching Protocols' not in response:
121-
print('Handshake response:', response)
125+
ws = websocket(ssl_sock, True)
126+
print('WebSocket object created')
127+
except Exception as e:
128+
print('Failed to create WebSocket object:', e)
122129
ssl_sock.close()
123-
raise Exception('Handshake failed')
124-
125-
# Push back extra bytes (WebSocket frame) to the socket
126-
if extra_bytes:
127-
print('Note: Extra bytes detected, will be handled by websocket module')
130+
raise
128131

129-
# Create WebSocket object
130-
ws = websocket(ssl_sock, True)
132+
# Send and receive data with retries
133+
try:
134+
bytes_written = ws.write('Hello, Secure WebSocket!')
135+
print('Sent message, bytes written:', bytes_written)
136+
except Exception as e:
137+
print('Failed to send message:', e)
138+
ws.close()
139+
raise
131140

132-
# Send and receive data
133-
ws.write('Hello, Secure WebSocket!')
134-
for _ in range(50):
135-
data = ws.read(1024)
136-
print('Received:', data)
137-
time.sleep_ms(100)
141+
# Try reading multiple times to catch initial message or echo
142+
max_attempts = 5
143+
read_timeout = 1 # Short timeout per read
144+
for attempt in range(max_attempts):
145+
try:
146+
data = ws.read(1024)
147+
print('Read attempt', attempt + 1, 'received:', data)
148+
if data:
149+
break
150+
time.sleep(0.5) # Wait briefly before retrying
151+
except Exception as e:
152+
print('Read attempt', attempt + 1, 'error:', e)
153+
time.sleep(0.5)
154+
if time.time() - start_time > read_timeout:
155+
print('Read timeout reached')
156+
break
138157

139158
# Close connection
140159
ws.close()
160+
print('Connection closed')

0 commit comments

Comments
 (0)