Skip to content

Commit

Permalink
webrepl: Changes for more webrepl features while making it smaller.
Browse files Browse the repository at this point in the history
This change:
- Moves the password checking to python
- Removes the special file transfer protocol
- Moves the REPL data to websocket binary packages

Signed-off-by: Felix Dörre <felix@dogcraft.de>
  • Loading branch information
felixdoerre committed Feb 29, 2024
1 parent ffb07db commit e100da0
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 9 deletions.
2 changes: 1 addition & 1 deletion micropython/net/webrepl/manifest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
metadata(description="WebREPL server.", version="0.1.0")
metadata(description="WebREPL server.", version="1.0.0")

module("webrepl.py", opt=3)
module("webrepl_setup.py", opt=3)
73 changes: 65 additions & 8 deletions micropython/net/webrepl/webrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,71 @@
import socket
import sys
import websocket
import _webrepl
import io

listen_s = None
client_s = None

DEBUG = 0

_DEFAULT_STATIC_HOST = const("https://micropython.org/webrepl/")
_DEFAULT_STATIC_HOST = const("https://felix.dogcraft.de/webrepl/")
_WELCOME_PROMPT = const("\r\nWebREPL connected\r\n>>> ")
static_host = _DEFAULT_STATIC_HOST

webrepl_pass = None

class WebreplWrapper(io.IOBase):
def __init__(self, sock):
self.sock = sock
self.sock.ioctl(9, 2)
if webrepl_pass is not None:
self.pw = bytearray(16)
self.pwPos = 0
self.sock.write("Password: ")
else:
self.pw = None
self.sock.write(_WELCOME_PROMPT)

def readinto(self, buf):
if self.pw is not None:
buf = bytearray(1)
while True:
l = self.sock.readinto(buf)
if l is None:
continue
if l <= 0:
return l
if buf[0] == 10 or buf[0] == 13:
print("Authenticating with:")
print(self.pw[0:self.pwPos])
if bytes(self.pw[0:self.pwPos]) == webrepl_pass:
self.pw = None
del self.pwPos
self.sock.write(_WELCOME_PROMPT)
break
else:
print(bytes(self.pw[0:self.pwPos]))
print(webrepl_pass)
self.sock.write("\r\nAccess denied\r\n")
return 0
else:
if self.pwPos < len(self.pw):
self.pw[self.pwPos] = buf[0]
self.pwPos = self.pwPos + 1
return self.sock.readinto(buf)

def write(self, buf):
if self.pw is not None:
return len(buf)
return self.sock.write(buf)

def ioctl(self, kind, arg):
if kind == 4:
self.sock.close()
return 0
return -1

def close(self):
self.sock.close()

def server_handshake(cl):
req = cl.makefile("rwb", 0)
Expand Down Expand Up @@ -84,7 +139,7 @@ def send_html(cl):
cl.send(static_host)
cl.send(
b"""\"></base>\r
<script src="webrepl_content.js"></script>\r
<script src="webreplv2_content.js"></script>\r
"""
)
cl.close()
Expand Down Expand Up @@ -127,7 +182,7 @@ def accept_conn(listen_sock):
client_s = cl

ws = websocket.websocket(cl, True)
ws = _webrepl._webrepl(ws)
ws = WebreplWrapper(ws)
cl.setblocking(False)
# notify REPL on socket incoming data (ESP32/ESP8266-only)
if hasattr(os, "dupterm_notify"):
Expand All @@ -147,10 +202,10 @@ def stop():


def start(port=8266, password=None, accept_handler=accept_conn):
global static_host
global static_host, webrepl_pass
stop()
webrepl_pass = password
if webrepl_pass is None:
if password is None:
try:
import webrepl_cfg

Expand All @@ -160,7 +215,9 @@ def start(port=8266, password=None, accept_handler=accept_conn):
except:
print("WebREPL is not configured, run 'import webrepl_setup'")

_webrepl.password(webrepl_pass)
if webrepl_pass is not None:
webrepl_pass = webrepl_pass.encode()

s = setup_conn(port, accept_handler)

if accept_handler is None:
Expand Down

0 comments on commit e100da0

Please sign in to comment.