diff --git a/draft_code/modwebsocket_test.py b/draft_code/modwebsocket_test.py index 76454667..8f2ec5a6 100644 --- a/draft_code/modwebsocket_test.py +++ b/draft_code/modwebsocket_test.py @@ -2,6 +2,7 @@ import socket import ssl import ubinascii from websocket import websocket +import time # Connect to Wi-Fi (disabled as per your code) if False: @@ -13,8 +14,15 @@ if False: print('Connected:', wlan.ifconfig()) # Resolve hostname +# Option 1: echo.websocket.events (unreliable) host = 'echo.websocket.events' port = 443 +handshake_path = '/' +# Option 2: ws.postman-echo.com (recommended for testing) +# host = 'ws.postman-echo.com' +# port = 443 +# handshake_path = '/raw' + try: addr_info = socket.getaddrinfo(host, port)[0][-1] print('Resolved address:', addr_info) @@ -41,17 +49,21 @@ except Exception as e: sock.close() raise +# Set socket to non-blocking +ssl_sock.setblocking(False) +print('Socket set to non-blocking') + # Perform WebSocket handshake key = ubinascii.b2a_base64(b'random_bytes_here').strip() handshake = ( - 'GET / HTTP/1.1\r\n' + 'GET {} HTTP/1.1\r\n' 'Host: {}\r\n' 'Upgrade: websocket\r\n' 'Connection: Upgrade\r\n' 'Sec-WebSocket-Key: {}\r\n' 'Sec-WebSocket-Version: 13\r\n' '\r\n' -).format(host, key.decode()) +).format(handshake_path, host, key.decode()) # Send handshake request try: @@ -63,12 +75,10 @@ except Exception as e: ssl_sock.close() raise -# Read HTTP response until \r\n\r\n +# Read HTTP response until \r\n\r\n (minimize reading) response_bytes = bytearray() -max_read = 1024 # Maximum bytes to read -read_timeout = 2 # Reduced timeout (seconds) -import time - +max_read = 1024 +read_timeout = 2 start_time = time.time() while len(response_bytes) < max_read: try: @@ -79,9 +89,29 @@ while len(response_bytes) < max_read: print('Received chunk, length:', len(chunk), 'bytes:', chunk) response_bytes.extend(chunk) print('Total bytes received:', len(response_bytes)) - # Check for end of HTTP headers (\r\n\r\n) if b'\r\n\r\n' in response_bytes: print('End of HTTP headers detected') + # Decode and verify HTTP response immediately + http_end = response_bytes.find(b'\r\n\r\n') + 4 + if http_end < 4: + ssl_sock.close() + raise Exception('Invalid HTTP response: no headers found') + http_response_bytes = response_bytes[:http_end] + try: + response = http_response_bytes.decode('utf-8') + print('Decoded HTTP response:', response) + except UnicodeError as e: + print('UnicodeError during decode:', e) + printable = ''.join(c if 32 <= ord(c) < 127 else '.' for c in http_response_bytes.decode('latin-1')) + print('Printable characters:', printable) + ssl_sock.close() + raise Exception('Failed to decode HTTP response') + if '101 Switching Protocols' not in response: + print('Handshake response:', response) + ssl_sock.close() + raise Exception('Handshake failed') + # Stop reading to leave WebSocket frame in socket buffer + print('Stopping read to preserve WebSocket frame') break except Exception as e: print('Error reading chunk:', e) @@ -90,51 +120,41 @@ while len(response_bytes) < max_read: print('Read timeout reached') break -# Inspect raw bytes -print('Raw response bytes:', response_bytes) -print('Raw response hex:', response_bytes.hex()) - -# Split HTTP response from any subsequent data -http_end = response_bytes.find(b'\r\n\r\n') + 4 -if http_end < 4: - ssl_sock.close() - raise Exception('Invalid HTTP response: no headers found') -http_response_bytes = response_bytes[:http_end] -extra_bytes = response_bytes[http_end:] if http_end < len(response_bytes) else b'' -print('HTTP response bytes:', http_response_bytes) -print('Extra bytes (if any):', extra_bytes) - -# Decode HTTP response -try: - response = http_response_bytes.decode('utf-8') - print('Decoded HTTP response:', response) -except UnicodeError as e: - print('UnicodeError during decode:', e) - # Dump printable characters as fallback - printable = ''.join(c if 32 <= ord(c) < 127 else '.' for c in http_response_bytes.decode('latin-1')) - print('Printable characters:', printable) - ssl_sock.close() - raise Exception('Failed to decode HTTP response') - -# Check for valid WebSocket handshake -if '101 Switching Protocols' not in response: - print('Handshake response:', response) - ssl_sock.close() - raise Exception('Handshake failed') - -# Push back extra bytes (WebSocket frame) to the socket -if extra_bytes: - print('Note: Extra bytes detected, will be handled by websocket module') - # Create WebSocket object -ws = websocket(ssl_sock, True) +try: + ws = websocket(ssl_sock, True) + print('WebSocket object created') +except Exception as e: + print('Failed to create WebSocket object:', e) + ssl_sock.close() + raise -# Send and receive data -ws.write('Hello, Secure WebSocket!') -for _ in range(50): - data = ws.read(1024) - print('Received:', data) - time.sleep_ms(100) +# Send and receive data with retries +try: + bytes_written = ws.write('Hello, Secure WebSocket!') + print('Sent message, bytes written:', bytes_written) +except Exception as e: + print('Failed to send message:', e) + ws.close() + raise + +# Try reading multiple times to catch initial message or echo +max_attempts = 5 +read_timeout = 1 # Short timeout per read +for attempt in range(max_attempts): + try: + data = ws.read(1024) + print('Read attempt', attempt + 1, 'received:', data) + if data: + break + time.sleep(0.5) # Wait briefly before retrying + except Exception as e: + print('Read attempt', attempt + 1, 'error:', e) + time.sleep(0.5) + if time.time() - start_time > read_timeout: + print('Read timeout reached') + break # Close connection ws.close() +print('Connection closed')