#!/usr/bin/env python3
"""
Two-origin HTTP server for the cross-fade() EXIF-orientation clamp bypass POC.

  * 127.0.0.1:39080 — "attacker" origin, serves poc.html and a SAME-origin copy
                      of the EXIF image (for the raw-pixel reference column).
  * 127.0.0.1:39081 — "victim" origin, serves oriented.jpg WITHOUT any CORS
                      headers, so it is an opaque cross-origin response when
                      loaded from 39080.
"""
import http.server
import os
import socketserver
import sys
import threading

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

class ReuseTCP(socketserver.TCPServer):
    allow_reuse_address = True

class AttackerHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=ROOT, **kw)
    def end_headers(self):
        self.send_header('Cache-Control', 'no-store')
        super().end_headers()

class VictimHandler(http.server.BaseHTTPRequestHandler):
    """Serves only oriented.jpg, deliberately WITHOUT Access-Control-Allow-Origin."""
    def do_GET(self):
        if self.path.split('?')[0] == '/oriented.jpg':
            with open(os.path.join(ROOT, 'oriented.jpg'), 'rb') as f:
                body = f.read()
            self.send_response(200)
            self.send_header('Content-Type', 'image/jpeg')
            self.send_header('Content-Length', str(len(body)))
            self.send_header('Cache-Control', 'no-store')
            # Intentionally no Access-Control-Allow-Origin header.
            self.end_headers()
            self.wfile.write(body)
        else:
            self.send_response(404)
            self.end_headers()
    def log_message(self, fmt, *args):
        sys.stderr.write('[victim:39081] ' + (fmt % args) + '\n')
        sys.stderr.flush()

def run(port, handler):
    httpd = ReuseTCP(('127.0.0.1', port), handler)
    print(f'serving on http://127.0.0.1:{port}/')
    httpd.serve_forever()

if __name__ == '__main__':
    threading.Thread(target=run, args=(39081, VictimHandler), daemon=True).start()
    run(39080, AttackerHandler)
