static.py
1 import falcon 2 import os 3 import mimetypes 4 5 class StaticResource: 6 def __init__(self, static_dir): 7 """ 8 Initialize the StaticResource with a specific static directory. 9 """ 10 self.static_dir = os.path.abspath(static_dir) 11 12 def on_get(self, req, resp, filepath=""): 13 """ 14 Handles requests for both root files and nested assets. 15 """ 16 # Ensure filepath is safely joined to prevent path traversal 17 file_path = os.path.normpath(os.path.join(self.static_dir, filepath)) 18 19 # Prevent path traversal by ensuring the file_path starts with static_dir 20 if not file_path.startswith(self.static_dir): 21 resp.status = falcon.HTTP_404 22 resp.text = "404 - Not Found" 23 return 24 25 # Handle fallback for missing assets 26 if not os.path.isfile(file_path): 27 if filepath == "favicon.ico": 28 resp.status = falcon.HTTP_404 29 resp.text = "404 - Favicon not found" 30 return 31 file_path = os.path.join(self.static_dir, "index.html") 32 33 # Determine MIME type 34 mime_type, _ = mimetypes.guess_type(file_path) 35 resp.content_type = mime_type or "application/octet-stream" 36 37 # Serve the file 38 try: 39 with open(file_path, "rb") as f: 40 resp.data = f.read() 41 except Exception as e: 42 resp.status = falcon.HTTP_500 43 resp.text = f"Error serving file: {str(e)}"