moving from python to GOAT nginx
This commit is contained in:
parent
7db8be7dc0
commit
02d47513d6
Binary file not shown.
93
backend.py
93
backend.py
@ -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 <host> <port> <file_root>""")
|
||||
|
||||
|
||||
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()
|
||||
111
nginx.conf
Normal file
111
nginx.conf
Normal file
@ -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;
|
||||
# }
|
||||
#}
|
||||
|
||||
}
|
||||
83
proxy.py
83
proxy.py
@ -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
|
||||
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
services: dict[str, str] = {
|
||||
"minirt": "localhost:7080",
|
||||
"minishell": "localhost:8080"
|
||||
}
|
||||
@ -63,7 +63,7 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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 <a href="https://github.com/raysan5/raylib">Raylib</a> 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 <a href="https://github.com/raysan5/raylib">Raylib</a> since it seemed more appropriate to use.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -71,7 +71,9 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@ -80,10 +82,9 @@
|
||||
|
||||
<div class="button-group">
|
||||
<a href="/minirt/wasm/miniRT.html" target="_blank" class="button">WASM Version (Raylib)</a>
|
||||
<a href="/minirt/vnc/vnc_lite.html?path=minirt/websockify&scale=resize" target="_blank" class="button">VNC Version (noVNC)</a>
|
||||
<a href="/proxy/minirt/vnc_lite.html?path=proxy/minirt/websockify&scale=resize" target="_blank" class="button">VNC Version (noVNC)</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -86,7 +86,7 @@
|
||||
Have fun!
|
||||
</p>
|
||||
<div id="shell-container">
|
||||
<button id="shell-start-button">
|
||||
<a href="/minishell/" id="shell-start-button">
|
||||
Start Shell
|
||||
</button>
|
||||
</div>
|
||||
|
||||
3
start_app.sh
Executable file
3
start_app.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
nginx -p $(pwd) -c ./nginx.conf -g "daemon off;"
|
||||
Loading…
x
Reference in New Issue
Block a user