diff --git a/default/home/.local/bin/ssi-server b/default/home/.local/bin/ssi-server new file mode 100755 index 0000000..7d3a0b1 --- /dev/null +++ b/default/home/.local/bin/ssi-server @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +''' +Use this in the same way as Python's SimpleHTTPServer: + + ./ssi_server.py [port] + +The only difference is that, for files ending in '.html', ssi_server will +inline SSI (Server Side Includes) of the form: + + + +Run ./ssi_server.py in this directory and visit localhost:8000 for an exmaple. +''' + +import os +import ssi +try: + # This works for Python 2 + from SimpleHTTPServer import SimpleHTTPRequestHandler + import SimpleHTTPServer +except ImportError: + # This works for Python 3 + from http.server import SimpleHTTPRequestHandler + import http.server as SimpleHTTPServer +import tempfile + + +class SSIRequestHandler(SimpleHTTPRequestHandler): + """Adds minimal support for directives. + + The key bit is translate_path, which intercepts requests and serves them + using a temporary file which inlines the #includes. + """ + + def __init__(self, request, client_address, server): + self.temp_files = [] + SimpleHTTPRequestHandler.__init__(self, request, client_address, server) + + def do_GET(self): + SimpleHTTPRequestHandler.do_GET(self) + self.delete_temp_files() + + def do_HEAD(self): + SimpleHTTPRequestHandler.do_HEAD(self) + self.delete_temp_files() + + def translate_path(self, path): + fs_path = SimpleHTTPRequestHandler.translate_path(self, path) + if self.path.endswith('/'): + for index in "index.html", "index.htm", "index.shtml": + index = os.path.join(fs_path, index) + if os.path.exists(index): + fs_path = index + break + + if (fs_path.endswith('.html') or fs_path.endswith(".shtml")) and os.path.exists(fs_path): + content = ssi.InlineIncludes(fs_path, path) + fs_path = self.create_temp_file(fs_path, content) + return fs_path + + def delete_temp_files(self): + for temp_file in self.temp_files: + os.remove(temp_file) + + def create_temp_file(self, original_path, content): + _, ext = os.path.splitext(original_path) + if ext == ".shtml": + ext = ".html" + fd, path = tempfile.mkstemp(suffix=ext) + try: + os.write(fd, content) # This works for Python 2 + except TypeError: + os.write(fd, bytes(content, 'UTF-8')) # This works for Python 3 + os.close(fd) + + self.temp_files.append(path) + return path + + +if __name__ == '__main__': + SimpleHTTPServer.test(HandlerClass=SSIRequestHandler) diff --git a/default/home/.local/lib/python3.13/site-packages/ssi.py b/default/home/.local/lib/python3.13/site-packages/ssi.py new file mode 100644 index 0000000..5b3b940 --- /dev/null +++ b/default/home/.local/lib/python3.13/site-packages/ssi.py @@ -0,0 +1,35 @@ +''' +Shared code for ssi_server.py and ssi_expander.py. +''' + +import re +import os.path +import warnings + +error_tmpl = """ +

+ %s +

+""" + +def InlineIncludes(path, web_path): + """Read a file, expanding statements.""" + def get_include_file_content(x): + file_to_read = x.group(2) + recursive_web_path = web_path + if len(os.path.dirname(web_path)) >2: + file_to_read = os.path.join(os.path.dirname(web_path),file_to_read)[1:] + recursive_web_path = "/%s/" % os.path.dirname(file_to_read) + if os.path.exists(file_to_read): + # Recursively process ssi calls in the included file + return InlineIncludes(file_to_read, recursive_web_path) + else: + error = "File not found: %s" % file_to_read + warnings.warn(error) + return error_tmpl % error + + content = open(path).read() + content = re.sub(r'', + get_include_file_content, + content) + return content diff --git a/default/include b/default/include index 8bc77e7..e2341ac 100644 --- a/default/include +++ b/default/include @@ -5,3 +5,5 @@ Scripts/ovpn-import.sh Scripts/destroy-podman-container.sh Scripts/create-podman-container.sh Scripts/create-podman-container-arm.sh +.local/lib/python3.13/site-packages/ssi.py +.local/bin/ssi-server