#!/usr/bin/env python3 """Tap Proxy — logs HTTP headers. Usage: python3 tap-proxy.py """ import http.server, urllib.request, sys from datetime import datetime PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8081 BACKEND = sys.argv[2] if len(sys.argv) > 2 else "127.0.0.1:80" LOG = (sys.argv[3] if len(sys.argv) > 3 else "/tmp") + "/tap-" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".log" BACKEND_URL = "http://" + BACKEND class Tap(http.server.BaseHTTPRequestHandler): def do_GET(self): self._tap('GET') def do_POST(self): self._tap('POST') def do_PUT(self): self._tap('PUT') def do_DELETE(self): self._tap('DELETE') def _tap(self, method): now = datetime.now().strftime('%H:%M:%S') msg = "\n" + "="*60 + "\n[" + now + "] " + method + " " + self.path msg += "\nClient: " + self.client_address[0] + "\n" + "-"*60 + "\n" for k, v in sorted(self.headers.items()): msg += " " + k + ": " + v + "\n" body = self.rfile.read(int(self.headers.get('Content-Length', 0))) if 'Content-Length' in self.headers else None req = urllib.request.Request(BACKEND_URL + self.path, data=body, method=method) for k, v in self.headers.items(): if k.lower() not in ('host', 'connection'): req.add_header(k, v) try: resp = urllib.request.urlopen(req, timeout=30) msg += "\nRESPONSE: " + str(resp.status) + "\n" for k, v in resp.getheaders(): msg += " " + k + ": " + v + "\n" self.send_response(resp.status) for k, v in resp.getheaders(): if k.lower() not in ('transfer-encoding', 'connection'): self.send_header(k, v) self.end_headers() self.wfile.write(resp.read()) except Exception as e: msg += "\nERROR: " + str(e) + "\n" self.send_error(502) with open(LOG, "a") as f: f.write(msg) def log_message(self, *args): pass print("Tap proxy :{0} -> {1}\nLog: {2}\nCtrl+C to stop".format(PORT, BACKEND_URL, LOG)) http.server.HTTPServer(('0.0.0.0', PORT), Tap).serve_forever()