diff options
-rw-r--r-- | mitmproxy/addons/browser.py | 30 | ||||
-rw-r--r-- | mitmproxy/flow.py | 6 | ||||
-rw-r--r-- | mitmproxy/platform/pf.py | 4 | ||||
-rw-r--r-- | mitmproxy/tools/console/consoleaddons.py | 4 | ||||
-rw-r--r-- | pathod/pathoc.py | 1 | ||||
-rw-r--r-- | test/mitmproxy/addons/test_browser.py | 13 | ||||
-rw-r--r-- | test/mitmproxy/net/test_tcp.py | 9 | ||||
-rw-r--r-- | test/mitmproxy/platform/test_pf.py | 1 | ||||
-rw-r--r-- | test/mitmproxy/test_http.py | 9 |
9 files changed, 62 insertions, 15 deletions
diff --git a/mitmproxy/addons/browser.py b/mitmproxy/addons/browser.py index 6e8b2585..247c356b 100644 --- a/mitmproxy/addons/browser.py +++ b/mitmproxy/addons/browser.py @@ -1,15 +1,27 @@ +import shutil import subprocess -import sys import tempfile +import typing from mitmproxy import command from mitmproxy import ctx -platformPaths = { - "linux": "google-chrome", - "win32": "chrome.exe", - "darwin": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", -} + +def get_chrome_executable() -> typing.Optional[str]: + for browser in ( + "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", + # https://stackoverflow.com/questions/40674914/google-chrome-path-in-windows-10 + r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", + r"C:\Program Files (x86)\Google\Application\chrome.exe", + # Linux binary names from Python's webbrowser module. + "google-chrome", + "chrome", + "chromium", + "chromium-browser", + ): + if shutil.which(browser): + return browser + return None class Browser: @@ -29,8 +41,8 @@ class Browser: else: self.done() - cmd = platformPaths.get(sys.platform) - if not cmd: # pragma: no cover + cmd = get_chrome_executable() + if not cmd: ctx.log.alert("Your platform is not supported yet - please submit a patch.") return @@ -59,4 +71,4 @@ class Browser: self.browser.kill() self.tdir.cleanup() self.browser = None - self.tdir = None
\ No newline at end of file + self.tdir = None diff --git a/mitmproxy/flow.py b/mitmproxy/flow.py index dc778404..111566b8 100644 --- a/mitmproxy/flow.py +++ b/mitmproxy/flow.py @@ -179,5 +179,7 @@ class Flow(stateobject.StateObject): if not self.intercepted: return self.intercepted = False - self.reply.ack() - self.reply.commit() + # If a flow is intercepted and then duplicated, the duplicated one is not taken. + if self.reply.state == "taken": + self.reply.ack() + self.reply.commit() diff --git a/mitmproxy/platform/pf.py b/mitmproxy/platform/pf.py index c0397d78..bb5eb515 100644 --- a/mitmproxy/platform/pf.py +++ b/mitmproxy/platform/pf.py @@ -1,3 +1,4 @@ +import re import sys @@ -8,6 +9,9 @@ def lookup(address, port, s): Returns an (address, port) tuple, or None. """ + # We may get an ipv4-mapped ipv6 address here, e.g. ::ffff:127.0.0.1. + # Those still appear as "127.0.0.1" in the table, so we need to strip the prefix. + address = re.sub("^::ffff:(?=\d+.\d+.\d+.\d+$)", "", address) s = s.decode() spec = "%s:%s" % (address, port) for i in s.split("\n"): diff --git a/mitmproxy/tools/console/consoleaddons.py b/mitmproxy/tools/console/consoleaddons.py index a65b26e1..7772545d 100644 --- a/mitmproxy/tools/console/consoleaddons.py +++ b/mitmproxy/tools/console/consoleaddons.py @@ -334,9 +334,9 @@ class ConsoleAddon: correct viewier, and fall back to the programs in $PAGER or $EDITOR if necessary. """ - fpart = getattr(f, part) + fpart = getattr(f, part, None) if not fpart: - raise exceptions.CommandError("Could not view part %s." % part) + raise exceptions.CommandError("Part must be either request or response, not %s." % part) t = fpart.headers.get("content-type") content = fpart.get_content(strict=False) if not content: diff --git a/pathod/pathoc.py b/pathod/pathoc.py index e1052750..20a915c0 100644 --- a/pathod/pathoc.py +++ b/pathod/pathoc.py @@ -244,6 +244,7 @@ class Pathoc(tcp.TCPClient): port=connect_to[1], path=None, http_version='HTTP/1.1', + headers=[(b"Host", connect_to[0].encode("idna"))], content=b'', ) self.wfile.write(net_http.http1.assemble_request(req)) diff --git a/test/mitmproxy/addons/test_browser.py b/test/mitmproxy/addons/test_browser.py index d1b32186..407a3fe6 100644 --- a/test/mitmproxy/addons/test_browser.py +++ b/test/mitmproxy/addons/test_browser.py @@ -5,7 +5,8 @@ from mitmproxy.test import taddons def test_browser(): - with mock.patch("subprocess.Popen") as po: + with mock.patch("subprocess.Popen") as po, mock.patch("shutil.which") as which: + which.return_value = "chrome" b = browser.Browser() with taddons.context() as tctx: b.start() @@ -18,3 +19,13 @@ def test_browser(): assert tctx.master.has_log("already running") b.done() assert not b.browser + + +def test_no_browser(): + with mock.patch("shutil.which") as which: + which.return_value = False + + b = browser.Browser() + with taddons.context() as tctx: + b.start() + assert tctx.master.has_log("platform is not supported") diff --git a/test/mitmproxy/net/test_tcp.py b/test/mitmproxy/net/test_tcp.py index 3e27929d..e9084be4 100644 --- a/test/mitmproxy/net/test_tcp.py +++ b/test/mitmproxy/net/test_tcp.py @@ -1,4 +1,5 @@ from io import BytesIO +import re import queue import time import socket @@ -95,7 +96,13 @@ class TestServerBind(tservers.ServerTestBase): class handler(tcp.BaseHandler): def handle(self): - self.wfile.write(str(self.connection.getpeername()).encode()) + # We may get an ipv4-mapped ipv6 address here, e.g. ::ffff:127.0.0.1. + # Those still appear as "127.0.0.1" in the table, so we need to strip the prefix. + peername = self.connection.getpeername() + address = re.sub("^::ffff:(?=\d+.\d+.\d+.\d+$)", "", peername[0]) + port = peername[1] + + self.wfile.write(str((address, port)).encode()) self.wfile.flush() def test_bind(self): diff --git a/test/mitmproxy/platform/test_pf.py b/test/mitmproxy/platform/test_pf.py index 3292d345..b048a697 100644 --- a/test/mitmproxy/platform/test_pf.py +++ b/test/mitmproxy/platform/test_pf.py @@ -15,6 +15,7 @@ class TestLookup: d = f.read() assert pf.lookup("192.168.1.111", 40000, d) == ("5.5.5.5", 80) + assert pf.lookup("::ffff:192.168.1.111", 40000, d) == ("5.5.5.5", 80) with pytest.raises(Exception, match="Could not resolve original destination"): pf.lookup("192.168.1.112", 40000, d) with pytest.raises(Exception, match="Could not resolve original destination"): diff --git a/test/mitmproxy/test_http.py b/test/mitmproxy/test_http.py index 4463961a..49e61e25 100644 --- a/test/mitmproxy/test_http.py +++ b/test/mitmproxy/test_http.py @@ -203,6 +203,15 @@ class TestHTTPFlow: f.resume() assert f.reply.state == "committed" + def test_resume_duplicated(self): + f = tflow.tflow() + f.intercept() + f2 = f.copy() + assert f.intercepted is f2.intercepted is True + f.resume() + f2.resume() + assert f.intercepted is f2.intercepted is False + def test_replace_unicode(self): f = tflow.tflow(resp=True) f.response.content = b"\xc2foo" |