feat: add support for HTTPS with --pem option in both Python and Node.js servers

This commit is contained in:
2026-05-22 00:08:50 +02:00
parent c0237886ee
commit fca0b84216
3 changed files with 60 additions and 11 deletions
+17 -3
View File
@@ -7,6 +7,8 @@ Behavior:
- Displays whether any incoming X-* headers were detected and lists them
- If User-Agent contains "curl" or "wget" (case-insensitive) the server
responds with Content-Type: text/plain; otherwise Content-Type: text/html.
- --pem path to a PEM bundle (cert chain + private key) to enable HTTPS;
without --pem the server uses plain HTTP.
- --look controls which HTML variant is returned for non-CLI agents:
* basic - plain HTML with no external references
* nice - includes Google Font "Noto Sans" (default)
@@ -30,6 +32,7 @@ Test:
import argparse
import signal
import ssl
import sys
from html import escape
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
@@ -303,7 +306,7 @@ class OkHandler(BaseHTTPRequestHandler):
(self.client_address[0], self.log_date_time_string(), format % args))
def run(bind: str, port: int, look: str):
def run(bind: str, port: int, look: str, pem: str | None = None):
addr = (bind, port)
try:
with ThreadingHTTPServer(addr, OkHandler) as httpd:
@@ -316,7 +319,16 @@ def run(bind: str, port: int, look: str):
# attach chosen look to server so handlers can use it as default
httpd.look = look
print(f"Serving on {bind}:{port} (default look={look}) (Ctrl-C to stop)")
if pem:
try:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain(pem)
except (ssl.SSLError, OSError) as e:
print(f"Cannot load PEM file '{pem}': {e}", file=sys.stderr)
sys.exit(1)
httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
scheme = "https" if pem else "http"
print(f"Serving on {scheme}://{bind}:{port} (default look={look}) (Ctrl-C to stop)")
httpd.serve_forever()
except KeyboardInterrupt:
print("\nShutting down server")
@@ -333,5 +345,7 @@ if __name__ == "__main__":
help="Port to listen on (default: 8080)")
parser.add_argument("--look", choices=VALID_LOOKS, default=VALID_LOOKS[1],
help="Default HTML look for non-cli agents (basic, nice, bootstrap, tailwind). Default: nice")
parser.add_argument("--pem", default=None, metavar="PEMFILE",
help="PEM bundle file (cert chain + private key) to enable HTTPS; plain HTTP if omitted")
args = parser.parse_args()
run(args.bind, args.port, args.look)
run(args.bind, args.port, args.look, args.pem)