Serve static content via websocket
authorBenjamin Braatz <bb@bbraatz.eu>
Wed, 13 Jan 2021 01:54:51 +0000 (02:54 +0100)
committerBenjamin Braatz <bb@bbraatz.eu>
Wed, 13 Jan 2021 01:54:51 +0000 (02:54 +0100)
graphit_controlpi/main.py
graphit_controlpi/websocket.py
setup.py

index 32ebf1004e5548e18daa45d88fb1598556de16e2..1b01b7a2342b03d5ef90cf14950aa4aec19be5b0 100644 (file)
@@ -12,7 +12,7 @@ async def setup():
     with open(sys.argv[1]) as json_data:
         conf = json.load(json_data)
         pins = await process_configuration(conf, out_queue)
-    await setup_websocket(pins, out_queue)
+    await setup_websocket(pins, out_queue, sys.argv[2])
 
 
 if __name__ == '__main__':
index 440994f9663a5f2db44f970989fa4c5c4688f71e..9d0ee8e60d3b8214ea86aaf270dc64bb18c11ef2 100644 (file)
@@ -3,6 +3,7 @@ import socket
 import json
 import asyncio
 import websockets
+from http import HTTPStatus
 
 
 async def process_command(command, pins, out_queue):
@@ -50,10 +51,36 @@ async def handler(pins, out_queue, websocket, path):
         task.cancel()
 
 
+async def process_request(sever_root, path, request_headers):
+    if 'Upgrade' in request_headers:
+        return
+    if path == '/':
+        path = '/index.html'
+    response_headers = [
+        ('Server', 'graphit_controlpi websocket server'),
+        ('Connection', 'close'),
+    ]
+    full_path = os.path.realpath(os.path.join(sever_root, path[1:]))
+    if os.path.commonpath((sever_root, full_path)) != sever_root or \
+            not os.path.exists(full_path) or not os.path.isfile(full_path):
+        return HTTPStatus.NOT_FOUND, [], b'404 NOT FOUND'
+    mime_type = 'application/octet-stream'
+    extension = full_path.split(".")[-1]
+    if extension == 'html':
+        mime_type = 'text/html'
+    elif extension == 'js':
+        mime_type = 'text/javascript'
+    elif extension == 'css':
+        mime_type = 'text/css'
+    response_headers.append(('Content-Type', mime_type))
+    body = open(full_path, 'rb').read()
+    response_headers.append(('Content-Length', str(len(body))))
+    return HTTPStatus.OK, response_headers, body
+
+
 def get_ip():
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     try:
-        # doesn't even have to be reachable
         s.connect(('10.255.255.255', 1))
         ip = s.getsockname()[0]
     except Exception:
@@ -63,8 +90,10 @@ def get_ip():
     return ip
 
 
-async def setup_websocket(pins, out_queue):
+async def setup_websocket(pins, out_queue, server_root):
     parameterised_handler = functools.partial(handler, pins, out_queue)
+    parameterised_process_request = functools.partial(process_request, server_root)
     hostname = get_ip()
-    await websockets.serve(parameterised_handler, hostname, 80)
+    await websockets.serve(parameterised_handler, hostname, 80,
+                           process_request=parameterised_process_request)
     print(f"Serving on ws://{hostname}:80")
index cf9e6979c47d4deac1ecd6a0fe46882f886be9dd..6f4a32865bd5777ce456371278bb44884cb96c93 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as readme_file:
 
 setuptools.setup(
     name="graphit-controlpi",
-    version="0.2.0",
+    version="0.2.1",
     author="Graph-IT GmbH",
     author_email="info@graph-it.com",
     description="Main Module for Machine Control Pi",