#!/usr/bin/env python3 """Both ends of an upload, for tests/shell/test-upload.sh. POST /sign/ mints a URL pointing at this server's /s3/, or fails, per the first line of /mint-mode PUT /s3/ the signed destination PUT /api/ headquarters' own route, which arena no longer uses Every request is appended to /requests as "METHOD path", which is what the shell test asserts on. /api/ is still served so the test can show that nothing arrives there, even from a manifest that offers it. The port is written to /port once bound, because the test asks for port 0 rather than guessing at a free one. """ import http.server import json import pathlib import sys SIGN_PREFIX = "/sign/" class Handler(http.server.BaseHTTPRequestHandler): directory = pathlib.Path() def log_message(self, *args): """Quiet. The test reads the request log, not stderr.""" def record(self): with (self.directory / "requests").open("a") as log: log.write(f"{self.command} {self.path}\n") def discard_body(self): length = int(self.headers.get("Content-Length") or 0) while length > 0: length -= len(self.rfile.read(min(length, 65536))) def do_POST(self): self.discard_body() self.record() mode = (self.directory / "mint-mode").read_text().strip() if mode != "ok" or not self.path.startswith(SIGN_PREFIX): self.send_response(500) self.end_headers() return name = self.path[len(SIGN_PREFIX) :] body = json.dumps( { "url": f"http://{self.headers['Host']}/s3/{name}", "method": "PUT", "expiresIn": 900, } ).encode() self.send_response(200) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def do_PUT(self): self.discard_body() self.record() self.send_response(200) self.end_headers() def main(): directory = pathlib.Path(sys.argv[1]) Handler.directory = directory server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler) (directory / "port").write_text(str(server.server_address[1])) server.serve_forever() if __name__ == "__main__": main()