Repaired websockets.
This commit is contained in:
		
							parent
							
								
									1de2c55966
								
							
						
					
					
						commit
						529606955a
					
				| @ -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