diff --git a/mitmproxy/addons/cut.py b/mitmproxy/addons/cut.py index 7d9a1f361..6bb52e844 100644 --- a/mitmproxy/addons/cut.py +++ b/mitmproxy/addons/cut.py @@ -1,6 +1,8 @@ import io import csv import typing +import os.path + from mitmproxy import command from mitmproxy import exceptions from mitmproxy import flow @@ -87,7 +89,8 @@ class Cut: append = False if path.startswith("+"): append = True - path = mitmproxy.types.Path(path[1:]) + epath = os.path.expanduser(path[1:]) + path = mitmproxy.types.Path(epath) try: if len(cuts) == 1 and len(flows) == 1: with open(path, "ab" if append else "wb") as fp: diff --git a/mitmproxy/addons/view.py b/mitmproxy/addons/view.py index 6da17b5bd..beaadcc6d 100644 --- a/mitmproxy/addons/view.py +++ b/mitmproxy/addons/view.py @@ -10,7 +10,6 @@ The View: """ import collections import typing -import os import blinker import sortedcontainers @@ -359,9 +358,8 @@ class View(collections.Sequence): """ Load flows into the view, without processing them with addons. """ - spath = os.path.expanduser(path) try: - with open(spath, "rb") as f: + with open(path, "rb") as f: for i in io.FlowReader(f).stream(): # Do this to get a new ID, so we can load the same file N times and # get new flows each time. It would be more efficient to just have a diff --git a/mitmproxy/types.py b/mitmproxy/types.py index 2d66bb8ec..23320c121 100644 --- a/mitmproxy/types.py +++ b/mitmproxy/types.py @@ -178,7 +178,7 @@ class _PathType(_BaseType): return ret def parse(self, manager: _CommandBase, t: type, s: str) -> str: - return s + return os.path.expanduser(s) def is_valid(self, manager: _CommandBase, typ: typing.Any, val: typing.Any) -> bool: return isinstance(val, str) diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py index b4a643ad7..35ff32415 100644 --- a/test/mitmproxy/test_types.py +++ b/test/mitmproxy/test_types.py @@ -2,6 +2,7 @@ import pytest import os import typing import contextlib +from unittest import mock import mitmproxy.exceptions import mitmproxy.types @@ -68,7 +69,10 @@ def test_path(tdata): b = mitmproxy.types._PathType() assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/foo") == "/foo" assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/bar") == "/bar" + with mock.patch.dict("os.environ", {"HOME": "/home/test"}): + assert b.parse(tctx.master.commands, mitmproxy.types.Path, "~/mitm") == "/home/test/mitm" assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, "foo") is True + assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, "~/mitm") is True assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, 3) is False def normPathOpts(prefix, match):