import aiohttp from aiohttp import web import asyncio from datetime import datetime minirt_vnc_host = "localhost" minirt_vnc_port = 7080 connections = {} max_duration = 60 async def proxy_http(request): service_name = request.match_info.get('service') target = request.match_info.get('target') if service_name == 'minirt': target = f"{minirt_vnc_host}:{minirt_vnc_port}/{target}" elif service_name == 'minishell': target = '' print(f"proxying to host {target}") async with aiohttp.ClientSession() as session: async with session.request( request.method, f"http://{target}", headers=request.headers, data=await request.read() ) as resp: return web.Response( body=await resp.read(), status=resp.status, headers=resp.headers ) async def proxy_ws(request: web.Request): service_name = request.match_info.get('service') if service_name in connections: return web.Response(text='Service already in use', status=409) ws = web.WebSocketResponse() await ws.prepare(request) connections[service_name] = (ws, datetime.now()) target = '' if service_name == 'minirt': target = f"{minirt_vnc_host}:{minirt_vnc_port}" elif service_name == 'minishell': target = '' try: async with aiohttp.ClientSession() as session: async with session.ws_connect(f"ws://{target}/websockify") as remote_ws: async def forward_to_remote(): async for msg in ws: if msg.type == aiohttp.WSMsgType.BINARY: await remote_ws.send_bytes(msg.data) async def forward_to_client(): async for msg in remote_ws: if msg.type == aiohttp.WSMsgType.BINARY: await ws.send_bytes(msg.data) async def check_timeout(): while True: await asyncio.sleep(10) elapsed = (datetime.now() - connections[service_name][1]).total_seconds() if elapsed > max_duration: await ws.close() break await asyncio.gather(forward_to_remote(), forward_to_client(), check_timeout()) finally: if service_name in connections: del connections[service_name] return ws