#!/usr/bin/env python3
"""
Two-origin HTTP server for LoAF sourceFunctionName opaque-bypass POC.

  Origin A:  http://localhost:18080/poc.html     (the attacker/embedder page)
  Origin B:  http://localhost:18081/sdk.js       (cross-origin "opaque" script -- NO CORS headers)

A loads B's script without a crossorigin attribute, so B's script is an
opaque (muted-errors) resource. B's script registers rAF callbacks that are
.bind()'d once (control) and twice (bypass). A then reads
PerformanceScriptTiming.sourceFunctionName for both.
"""
import http.server
import socketserver
import threading
import os
import sys

ROOT = os.path.dirname(os.path.abspath(__file__))

class QuietHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=ROOT, **kw)
    def log_message(self, fmt, *a):
        sys.stderr.write("[http] " + (fmt % a) + "\n")
    def end_headers(self):
        # Intentionally NO Access-Control-Allow-Origin header -> opaque when loaded cross-origin without crossorigin=.
        self.send_header("Cache-Control", "no-store")
        super().end_headers()

class ReuseTCP(socketserver.TCPServer):
    allow_reuse_address = True

def serve(port):
    httpd = ReuseTCP(("127.0.0.1", port), QuietHandler)
    print(f"[server] listening on http://127.0.0.1:{port}/", flush=True)
    httpd.serve_forever()

if __name__ == "__main__":
    threading.Thread(target=serve, args=(18081,), daemon=True).start()
    serve(18080)
