From 434dabaa5ebc226fdbe5bc2e68e1561b1bdcd9d0 Mon Sep 17 00:00:00 2001 From: xmo-odoo Date: Fri, 23 May 2025 16:49:08 +0200 Subject: [PATCH] Add portfile support (#7724) Convenient when manipulating mitmproxy programmatically, as it's often useful to specify port 0 (for all sorts of servers) but then the user needs a way to retrieve the actual port being used. mitmproxy logs the bound ports out by default, however because it logs to the fully buffered stdout *and* can generate quite a bit of log, this tends to be inconvenient. Writing out a file at a user-specified location makes it much easier for them to poll, and using json even if there is a minor race the user can just keep reading until they see a valid JSON file. --- examples/contrib/portfile.py | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 examples/contrib/portfile.py diff --git a/examples/contrib/portfile.py b/examples/contrib/portfile.py new file mode 100644 index 000000000..7c6bb6bf3 --- /dev/null +++ b/examples/contrib/portfile.py @@ -0,0 +1,40 @@ +import json +import pathlib +from typing import Optional + +from mitmproxy import ctx + + +class PortFile: + def load(self, loader): + loader.add_option( + name="datadir", + typespec=Optional[str], + default=None, + help="Creates `portfile` mapping proxies (by mode spec) to the port " + "they use in the provided directory.", + ) + + def running(self): + if not ctx.options.datadir: + return + + datadir = pathlib.Path(ctx.options.datadir) + if not datadir.is_dir(): + ctx.log.warning("%s is not a directory", datadir) + return + + proxies = ctx.master.addons.get("proxyserver") + modemap = { + instance.mode.full_spec: addr[1] + for instance in proxies.servers + # assumes all listen_addrs of a given instance are bound + # to the same port, but as far as I can tell mitmproxy + # works very hard to try and make it so + if (addr := next(iter(instance.listen_addrs), None)) + } + with datadir.joinpath("portfile").open("w", encoding="utf-8") as fp: + json.dump(modemap, fp) + + +addons = [PortFile()]