aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/addons/browser.py30
-rw-r--r--mitmproxy/flow.py6
-rw-r--r--mitmproxy/platform/pf.py4
-rw-r--r--mitmproxy/tools/console/consoleaddons.py4
-rw-r--r--pathod/pathoc.py1
-rw-r--r--test/mitmproxy/addons/test_browser.py13
-rw-r--r--test/mitmproxy/net/test_tcp.py9
-rw-r--r--test/mitmproxy/platform/test_pf.py1
-rw-r--r--test/mitmproxy/test_http.py9
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"