diff --git a/.env b/.env index e69de29..8b13789 100644 --- a/.env +++ b/.env @@ -0,0 +1 @@ + diff --git a/__pycache__/proxy.cpython-314.pyc b/__pycache__/proxy.cpython-314.pyc index ae62ba3..5a24722 100644 Binary files a/__pycache__/proxy.cpython-314.pyc and b/__pycache__/proxy.cpython-314.pyc differ diff --git a/backend.py b/backend.py deleted file mode 100644 index 62527a4..0000000 --- a/backend.py +++ /dev/null @@ -1,93 +0,0 @@ -import sys -import os -from aiohttp import web - -from proxy import proxy_ws, proxy_http - -[_, host, port, file_root] = sys.argv - -def print_usage(): - print("""Usage: python3 ./backend.py """) - - -async def handle_service(request: web.Request): - [service, medium, target] = [ - request.match_info.get('service'), - request.match_info.get('medium'), - request.match_info.get('target') - ] - - if not target or target == '': - return web.json_response(status=404, data={"success": "false", "message": "Not Found"}) - - if 'vnc' in request.url.path: - return await proxy_http(request) - - if not service or not medium: - return web.json_response({"success": "false", "message": "Missing Serice or Medium"}) - - if not target: - target = "index.html" - - serve_path = f"{file_root}/service/{service}/{medium}/{target}" - - if not os.path.exists(serve_path): - data = { "success": "false", "message": "Not Found" } - return web.json_response( - status=404, - data=data, - ) - return web.FileResponse(serve_path) - - -async def serve_http(request: web.Request): - path_info = request.match_info.get('path_info', '') - - print(f"Req: {request} with path: {path_info}") - - if '..' in path_info: - data = {"success": "false", "message": "Forbidden"} - return web.json_response( - status=403, - data=data, - content_type='application/json' - ) - elif path_info == '': - path_info = "index.html" - - serve_path = f"{file_root}/{path_info}" - - print(f"looking for path {serve_path}") - - if not os.path.exists(serve_path): - data = { "success": "false", "message": "Not Found" } - return web.json_response( - status=404, - data=data, - ) - return web.FileResponse(serve_path) - -def build_http_server(): - app = web.Application() - app.add_routes([ - web.get('/{service}/{medium}/{target:.*}', handle_service), - web.get("/{service}/websockify", proxy_ws), - web.get("/{path_info:.*}", serve_http), - ]) - - return app - -def main(host, port): - app = build_http_server() - web.run_app(app, host=host, port=int(port)) - -try: - main(host, port) - -except ValueError as e: - print(f"Argv Error: {e}") - print_usage() - -except Exception as e: - print("Caught exception: {e}") - print_usage() diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..2f6d8a6 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,111 @@ +#user http; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +pid /tmp/nginx.pid; + + +# Load all installed modules +include /etc/nginx/modules.d/*.conf; + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + + #gzip on; + + upstream minirt { + # server 127.0.0.1:7080; + } + + upstream minishell { + # server 127.0.0.1:6080; + } + + server { + listen 8080; + server_name localhost; + root ./site; + + #charset koi8-r; + + #access_log logs/host.access.log main; + + location / { + try_files $uri $uri/ /index.html; + } + + location /proxy/minirt/websockify { + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + + proxy_read_timeout 61s; + proxy_buffering off; + proxy_pass http://minirt/websockify; + } + + location /proxy/minirt/ { + proxy_pass http://minirt/; + } + } + + + # another virtual host using mix of IP-, name-, and port-based configuration + # + #server { + # listen 8000; + # listen somename:8080; + # server_name somename alias another.alias; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + + + # HTTPS server + # + #server { + # listen 443 ssl; + # server_name localhost; + + # ssl_certificate cert.pem; + # ssl_certificate_key cert.key; + + # ssl_session_cache shared:SSL:1m; + # ssl_session_timeout 5m; + + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + +} diff --git a/proxy.py b/proxy.py deleted file mode 100644 index a2a99fa..0000000 --- a/proxy.py +++ /dev/null @@ -1,83 +0,0 @@ -import aiohttp -from aiohttp import web -import asyncio -from datetime import datetime - -from services import services - - -connections = {} -max_duration = 60 - -async def proxy_http(request: web.Request): - service_name = request.match_info.get('service') - - if not service_name or not services[service_name]: - return web.json_response(status=404, data={ "success": "false", "message": "Unknown service name" }) - url = services[service_name] - - target = request.match_info.get('target') - target = f"{url}/{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) - - if not service_name or not services[service_name]: - return web.json_response(status=404, data={ "success": "false", "message": "Unknown service name" }) - - ws = web.WebSocketResponse() - await ws.prepare(request) - - connections[service_name] = (ws, datetime.now()) - - url = services[service_name] - - target = request.match_info.get('target') - target = f"{url}/{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 - - diff --git a/services.py b/services.py deleted file mode 100644 index 2fe9c3e..0000000 --- a/services.py +++ /dev/null @@ -1,4 +0,0 @@ -services: dict[str, str] = { - "minirt": "localhost:7080", - "minishell": "localhost:8080" -} diff --git a/site/minirt.html b/site/minirt.html index cffa568..e258f5d 100644 --- a/site/minirt.html +++ b/site/minirt.html @@ -63,7 +63,7 @@

- As a final note: since we finished the project, I was planning on showcasing it here, and so I have reimplemented the graphical part to use Raylib since it seemed more appropriate to use. + As a final note: since we finished the project, I was planning on showcasing it here, and so I have reimplemented the rendering layer to use Raylib since it seemed more appropriate to use.

@@ -71,7 +71,9 @@

- There are two ways to run the app: either directly in your browser with the WASM compiled program, or over a live noVNC connection to a running instance on the server. The raytracer itself is multithreaded, but since JS/WASM runs on a single thread, the WASM version is very slow. I scaled down the resolution for that version in order to have it not run at -5 FPS. + There are two ways to run the app: either directly in your browser with the WASM compiled program, or over a live noVNC connection to a running instance on the server. The connection to the VNC server will automatically be closed after 60 seconds in order to save resources. +

+

The raytracer itself is multithreaded, but since JS/WASM runs on a single thread, the WASM version is very slow. I scaled down the resolution for that version in order to have it not run at -5 FPS.

@@ -80,10 +82,9 @@

- diff --git a/site/minishell.html b/site/minishell.html index 12fa85f..a168ead 100644 --- a/site/minishell.html +++ b/site/minishell.html @@ -86,7 +86,7 @@ Have fun!

diff --git a/start_app.sh b/start_app.sh new file mode 100755 index 0000000..6b1dd65 --- /dev/null +++ b/start_app.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +nginx -p $(pwd) -c ./nginx.conf -g "daemon off;"