mitmproxy/examples/contrib/portfile.py
xmo-odoo 434dabaa5e
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.
2025-05-23 16:49:08 +02:00

40 lines
1.2 KiB
Python

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()]