wallarm/sources/python/tap-proxy.py

54 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Tap Proxy — logs HTTP headers. Usage: python3 tap-proxy.py <port> <backend_host:port> <log_dir>"""
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 += "\nBACKEND: " + str(e) + "\n"
self.send_response(502)
self.send_header('Content-Type', 'text/plain')
self.end_headers()
self.wfile.write(b"Backend unreachable: " + str(e).encode())
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()