Fix terminal: use create_process with binary encoding for PTY I/O
This commit is contained in:
@@ -28,16 +28,19 @@ async def ws_endpoint(websocket: WebSocket, token: str = Query("")):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
chan, session = await conn.create_session(
|
process = await conn.create_process(
|
||||||
asyncssh.SSHClientProcess, term_type="xterm-256color",
|
term_type="xterm-256color", term_size=(80, 24),
|
||||||
term_size=(80, 24),
|
encoding=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def read_ssh():
|
async def read_ssh():
|
||||||
try:
|
try:
|
||||||
async for data in chan.stdout:
|
while True:
|
||||||
await websocket.send_bytes(data.encode() if isinstance(data, str) else data)
|
data = await process.stdout.read(4096)
|
||||||
except (asyncssh.Error, WebSocketDisconnect):
|
if not data:
|
||||||
|
break
|
||||||
|
await websocket.send_bytes(data)
|
||||||
|
except (asyncssh.Error, WebSocketDisconnect, asyncio.CancelledError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
read_task = asyncio.create_task(read_ssh())
|
read_task = asyncio.create_task(read_ssh())
|
||||||
@@ -50,14 +53,15 @@ async def ws_endpoint(websocket: WebSocket, token: str = Query("")):
|
|||||||
if data[0:1] == b"\x01" and len(data) == 5:
|
if data[0:1] == b"\x01" and len(data) == 5:
|
||||||
cols = struct.unpack("!H", data[1:3])[0]
|
cols = struct.unpack("!H", data[1:3])[0]
|
||||||
rows = struct.unpack("!H", data[3:5])[0]
|
rows = struct.unpack("!H", data[3:5])[0]
|
||||||
chan.change_terminal_size(cols, rows)
|
process.channel.change_terminal_size(cols, rows)
|
||||||
else:
|
else:
|
||||||
chan.write(data.decode("utf-8", errors="replace"))
|
process.stdin.write(data)
|
||||||
elif "text" in msg and msg["text"]:
|
elif "text" in msg and msg["text"]:
|
||||||
chan.write(msg["text"])
|
process.stdin.write(msg["text"].encode())
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
read_task.cancel()
|
read_task.cancel()
|
||||||
|
process.close()
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|||||||
Reference in New Issue
Block a user