From 33bba38b03496f05f15f945e32a5af5d1d77906f Mon Sep 17 00:00:00 2001 From: Agustin Bacigalup Date: Wed, 23 Mar 2022 10:04:38 -0300 Subject: [PATCH] Add httpdump.py example (#5190) * add httpdump.py example * update CHANGELOG.md * delete print() statement * fix flake8? --- CHANGELOG.md | 3 +- examples/contrib/httpdump.py | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 examples/contrib/httpdump.py diff --git a/CHANGELOG.md b/CHANGELOG.md index cebf667df..b2c7557b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## Unreleased: mitmproxy next -* Add flatpak support to the browser addon (@pauloromeira) +* Add flatpak support to the browser addon (#5200, @pauloromeira) +* Add example addon to dump contents to files based on a filter expression (#5190, @redraw) ## 19 March 2022: mitmproxy 8.0.0 diff --git a/examples/contrib/httpdump.py b/examples/contrib/httpdump.py new file mode 100644 index 000000000..c9e9eede3 --- /dev/null +++ b/examples/contrib/httpdump.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# dump content to files based on a filter +# usage: mitmdump -s httpdump.py "~ts application/json" +# +# options: +# - dumper_folder: content dump destination folder (default: ./httpdump) +# - open_browser: open integrated browser with proxy configured at start (default: true) +# +# remember to add your own mitmproxy authorative certs in your browser/os! +# certs docs: https://docs.mitmproxy.org/stable/concepts-certificates/ +# filter expressions docs: https://docs.mitmproxy.org/stable/concepts-filters/ +import os +import mimetypes +from pathlib import Path + +from mitmproxy import flowfilter +from mitmproxy import ctx, http + + +class HTTPDump: + def load(self, loader): + self.filter = ctx.options.dumper_filter + + loader.add_option( + name = "dumper_folder", + typespec = str, + default = "httpdump", + help = "content dump destination folder", + ) + loader.add_option( + name = "open_browser", + typespec = bool, + default = True, + help = "open integrated browser at start" + ) + + def running(self): + if ctx.options.open_browser: + ctx.master.commands.call("browser.start") + + def configure(self, updated): + if "dumper_filter" in updated: + self.filter = ctx.options.dumper_filter + + def response(self, flow: http.HTTPFlow) -> None: + if flowfilter.match(self.filter, flow): + self.dump(flow) + + def dump(self, flow: http.HTTPFlow): + if not flow.response: + return + + # create dir + folder = Path(ctx.options.dumper_folder) / flow.request.host + if not folder.exists(): + os.makedirs(folder) + + # calculate path + path = "-".join(flow.request.path_components) + filename = "-".join([path, flow.id]) + content_type = flow.response.headers.get("content-type", "").split(";")[0] + ext = mimetypes.guess_extension(content_type) or "" + filepath = folder / f"{filename}{ext}" + + # dump to file + if flow.response.content: + with open(filepath, "wb") as f: + f.write(flow.response.content) + ctx.log.info(f"Saved! {filepath}") + + +addons = [HTTPDump()]