Repaired websockets.
This commit is contained in:
parent
1de2c55966
commit
529606955a
src/snek
@ -180,8 +180,8 @@ class Application(BaseApplication):
|
|||||||
|
|
||||||
executor = ThreadPoolExecutor(max_workers=100)
|
executor = ThreadPoolExecutor(max_workers=100)
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
#loop = asyncio.get_event_loop()
|
||||||
loop.set_default_executor(executor)
|
#loop.set_default_executor(executor)
|
||||||
|
|
||||||
app = Application(db_path="sqlite:///snek.db")
|
app = Application(db_path="sqlite:///snek.db")
|
||||||
|
|
||||||
|
@ -13,80 +13,42 @@ commands = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TerminalSession:
|
class TerminalSession:
|
||||||
|
|
||||||
async def ensure_process(self):
|
|
||||||
if self.process:
|
|
||||||
return
|
|
||||||
self.process = await asyncio.create_subprocess_exec(
|
|
||||||
*self.command.split(" "),
|
|
||||||
stdin=self.slave,
|
|
||||||
stdout=self.slave,
|
|
||||||
stderr=self.slave,bufsize=0,
|
|
||||||
universal_newlines=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self,command):
|
def __init__(self,command):
|
||||||
self.master, self.slave = pty.openpty()
|
self.master, self.slave = pty.openpty()
|
||||||
self.sockets =[]
|
self.sockets =[]
|
||||||
self.buffer = b''
|
self.history = b''
|
||||||
self.process = None
|
self.history_size = 1024*20
|
||||||
|
self.process = subprocess.Popen(
|
||||||
#self.process = subprocess.Popen(
|
command.split(" "),
|
||||||
# command.split(" "),
|
stdin=self.slave,
|
||||||
# stdin=self.slave,
|
stdout=self.slave,
|
||||||
# stdout=self.slave,
|
stderr=self.slave,
|
||||||
# stderr=self.slave,
|
bufsize=0,
|
||||||
# bufsize=0,
|
universal_newlines=True
|
||||||
# universal_newlines=True
|
)
|
||||||
#)
|
|
||||||
|
|
||||||
|
async def add_websocket(self, ws):
|
||||||
|
asyncio.create_task(self.read_output(ws))
|
||||||
|
|
||||||
async def read_output(self, ws):
|
async def read_output(self, ws):
|
||||||
await self.ensure_process()
|
|
||||||
self.sockets.append(ws)
|
self.sockets.append(ws)
|
||||||
if len(self.sockets) > 1:
|
if len(self.sockets) > 1 and self.buffer:
|
||||||
start = self.buffer.index(b'\n')
|
start = 0
|
||||||
await ws.send_bytes(self.buffer[start:])
|
|
||||||
return
|
|
||||||
while True:
|
|
||||||
try:
|
try:
|
||||||
async for data in self.process.stdout:
|
start = self.history.index(b'\n')
|
||||||
if not data:
|
except ValueError:
|
||||||
break
|
pass
|
||||||
self.buffer += data
|
await ws.send_bytes(self.history[start:])
|
||||||
if len(self.buffer) > 10000:
|
|
||||||
self.buffer = self.buffer[:-10000]
|
|
||||||
try:
|
|
||||||
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
|
|
||||||
except:
|
|
||||||
self.sockets.remove(ws)
|
|
||||||
except:
|
|
||||||
print("Terminating process")
|
|
||||||
self.process.terminate()
|
|
||||||
print("Terminated process")
|
|
||||||
for ws in self.sockets:
|
|
||||||
try:
|
|
||||||
await ws.close()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
break
|
|
||||||
|
|
||||||
async def read_outputa(self, ws):
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
self.sockets.append(ws)
|
|
||||||
if len(self.sockets) > 1:
|
|
||||||
start = self.buffer.index(b'\n')
|
|
||||||
await ws.send_bytes(self.buffer[start:])
|
|
||||||
return
|
return
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
data = await loop.run_in_executor(None, os.read, self.master, 1024)
|
data = await loop.run_in_executor(None, os.read, self.master, 1024)
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
self.buffer += data
|
self.history += data
|
||||||
if len(self.buffer) > 10000:
|
if len(self.history) > self.history_size:
|
||||||
self.buffer = self.buffer[:-10000]
|
self.history = self.history[:0-self.history_size]
|
||||||
try:
|
try:
|
||||||
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
|
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
|
||||||
except:
|
except:
|
||||||
@ -103,7 +65,10 @@ class TerminalSession:
|
|||||||
break
|
break
|
||||||
|
|
||||||
async def write_input(self, data):
|
async def write_input(self, data):
|
||||||
await self.ensure_process()
|
try:
|
||||||
os.write(self.master, data.encode())
|
data = data.encode()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
await asyncio.get_event_loop().run_in_executor(
|
||||||
|
None, os.write, self.master, data
|
||||||
|
)
|
||||||
|
@ -37,7 +37,8 @@ class TerminalSocketView(BaseView):
|
|||||||
if not session:
|
if not session:
|
||||||
self.user_sessions[user["uid"]] = TerminalSession(command=command)
|
self.user_sessions[user["uid"]] = TerminalSession(command=command)
|
||||||
session = self.user_sessions[user["uid"]]
|
session = self.user_sessions[user["uid"]]
|
||||||
asyncio.create_task(session.read_output(ws))
|
await session.add_websocket(ws)
|
||||||
|
#asyncio.create_task(session.read_output(ws))
|
||||||
|
|
||||||
async for msg in ws:
|
async for msg in ws:
|
||||||
if msg.type == aiohttp.WSMsgType.BINARY:
|
if msg.type == aiohttp.WSMsgType.BINARY:
|
||||||
|
Loading…
Reference in New Issue
Block a user