diff --git a/CHANGELOG.md b/CHANGELOG.md index ac7fb048b..fdca1b846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ If you depend on these features, please raise your voice in * Add option `export_preserve_original_ip` to force exported command to connect to IP from original request. Only supports curl at the moment. (@dkasak) * Major proxy protocol testing (@r00t-) * Switch Docker image release to be based on Debian (@PeterDaveHello) +* Multiple Browsers: The `browser.start` command may be executed more than once to start additional + browser sessions. (@rbdixon) * --- TODO: add new PRs above this line --- * ... and various other fixes, documentation improvements, dependency version bumps, etc. diff --git a/mitmproxy/addons/browser.py b/mitmproxy/addons/browser.py index fadc96fc5..e3aa24d7a 100644 --- a/mitmproxy/addons/browser.py +++ b/mitmproxy/addons/browser.py @@ -27,8 +27,8 @@ def get_chrome_executable() -> typing.Optional[str]: class Browser: - browser = None - tdir = None + browser: typing.List[subprocess.Popen] = [] + tdir: typing.List[tempfile.TemporaryDirectory] = [] @command.command("browser.start") def start(self) -> None: @@ -36,23 +36,20 @@ class Browser: Start an isolated instance of Chrome that points to the currently running proxy. """ - if self.browser: - if self.browser.poll() is None: - ctx.log.alert("Browser already running") - return - else: - self.done() + if len(self.browser) > 0: + ctx.log.alert("Starting additional browser") cmd = get_chrome_executable() if not cmd: ctx.log.alert("Your platform is not supported yet - please submit a patch.") return - self.tdir = tempfile.TemporaryDirectory() - self.browser = subprocess.Popen( + tdir = tempfile.TemporaryDirectory() + self.tdir.append(tdir) + self.browser.append(subprocess.Popen( [ cmd, - "--user-data-dir=%s" % str(self.tdir.name), + "--user-data-dir=%s" % str(tdir.name), "--proxy-server={}:{}".format( ctx.options.listen_host or "127.0.0.1", ctx.options.listen_port @@ -66,11 +63,12 @@ class Browser: ], stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL, - ) + )) def done(self): - if self.browser: - self.browser.kill() - self.tdir.cleanup() - self.browser = None - self.tdir = None \ No newline at end of file + for browser in self.browser: + browser.kill() + for tdir in self.tdir: + tdir.cleanup() + self.browser = [] + self.tdir = [] \ No newline at end of file diff --git a/test/mitmproxy/addons/test_browser.py b/test/mitmproxy/addons/test_browser.py index 44adbe5a3..ac009e4d9 100644 --- a/test/mitmproxy/addons/test_browser.py +++ b/test/mitmproxy/addons/test_browser.py @@ -15,9 +15,8 @@ async def test_browser(): assert po.called b.start() - b.browser.poll = lambda: None - b.start() - await tctx.master.await_log("already running") + await tctx.master.await_log("Starting additional browser") + assert len(b.browser) == 2 b.done() assert not b.browser