mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 08:11:00 +00:00
Merge pull request #2297 from cortesi/flowcmd
commands: view.order.options, view.marked.toggle, view.create
This commit is contained in:
commit
29ce5a83d2
@ -19,6 +19,7 @@ import mitmproxy.flow
|
|||||||
from mitmproxy import flowfilter
|
from mitmproxy import flowfilter
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
from mitmproxy import command
|
from mitmproxy import command
|
||||||
|
from mitmproxy import connections
|
||||||
from mitmproxy import ctx
|
from mitmproxy import ctx
|
||||||
from mitmproxy import io
|
from mitmproxy import io
|
||||||
from mitmproxy import http # noqa
|
from mitmproxy import http # noqa
|
||||||
@ -201,7 +202,18 @@ class View(collections.Sequence):
|
|||||||
self.sig_view_refresh.send(self)
|
self.sig_view_refresh.send(self)
|
||||||
|
|
||||||
# API
|
# API
|
||||||
def toggle_marked(self):
|
@command.command("view.order.options")
|
||||||
|
def order_options(self) -> typing.Sequence[str]:
|
||||||
|
"""
|
||||||
|
A list of all the orders we support.
|
||||||
|
"""
|
||||||
|
return list(sorted(self.orders.keys()))
|
||||||
|
|
||||||
|
@command.command("view.marked.toggle")
|
||||||
|
def toggle_marked(self) -> None:
|
||||||
|
"""
|
||||||
|
Toggle whether to show marked views only.
|
||||||
|
"""
|
||||||
self.show_marked = not self.show_marked
|
self.show_marked = not self.show_marked
|
||||||
self._refilter()
|
self._refilter()
|
||||||
|
|
||||||
@ -341,6 +353,16 @@ class View(collections.Sequence):
|
|||||||
raise exceptions.CommandError("Invalid flow filter: %s" % spec)
|
raise exceptions.CommandError("Invalid flow filter: %s" % spec)
|
||||||
return [i for i in self._store.values() if filt(i)]
|
return [i for i in self._store.values() if filt(i)]
|
||||||
|
|
||||||
|
@command.command("view.create")
|
||||||
|
def create(self, method: str, url: str) -> None:
|
||||||
|
req = http.HTTPRequest.make(method.upper(), url)
|
||||||
|
c = connections.ClientConnection.make_dummy(("", 0))
|
||||||
|
s = connections.ServerConnection.make_dummy((req.host, req.port))
|
||||||
|
f = http.HTTPFlow(c, s)
|
||||||
|
f.request = req
|
||||||
|
f.request.headers["Host"] = req.host
|
||||||
|
self.add([f])
|
||||||
|
|
||||||
# Event handlers
|
# Event handlers
|
||||||
def configure(self, updated):
|
def configure(self, updated):
|
||||||
if "view_filter" in updated:
|
if "view_filter" in updated:
|
||||||
|
@ -7,7 +7,6 @@ from mitmproxy import options
|
|||||||
from mitmproxy import controller
|
from mitmproxy import controller
|
||||||
from mitmproxy import eventsequence
|
from mitmproxy import eventsequence
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
from mitmproxy import connections
|
|
||||||
from mitmproxy import command
|
from mitmproxy import command
|
||||||
from mitmproxy import http
|
from mitmproxy import http
|
||||||
from mitmproxy import log
|
from mitmproxy import log
|
||||||
@ -78,9 +77,6 @@ class Master:
|
|||||||
self.start()
|
self.start()
|
||||||
try:
|
try:
|
||||||
while not self.should_exit.is_set():
|
while not self.should_exit.is_set():
|
||||||
# Don't choose a very small timeout in Python 2:
|
|
||||||
# https://github.com/mitmproxy/mitmproxy/issues/443
|
|
||||||
# TODO: Lower the timeout value if we move to Python 3.
|
|
||||||
self.tick(0.1)
|
self.tick(0.1)
|
||||||
finally:
|
finally:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
@ -109,22 +105,6 @@ class Master:
|
|||||||
self.should_exit.set()
|
self.should_exit.set()
|
||||||
self.addons.trigger("done")
|
self.addons.trigger("done")
|
||||||
|
|
||||||
def create_request(self, method, url):
|
|
||||||
"""
|
|
||||||
Create a new artificial and minimalist request also adds it to flowlist.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError, if the url is malformed.
|
|
||||||
"""
|
|
||||||
req = http.HTTPRequest.make(method, url)
|
|
||||||
c = connections.ClientConnection.make_dummy(("", 0))
|
|
||||||
s = connections.ServerConnection.make_dummy((req.host, req.port))
|
|
||||||
|
|
||||||
f = http.HTTPFlow(c, s)
|
|
||||||
f.request = req
|
|
||||||
self.load_flow(f)
|
|
||||||
return f
|
|
||||||
|
|
||||||
def load_flow(self, f):
|
def load_flow(self, f):
|
||||||
"""
|
"""
|
||||||
Loads a flow
|
Loads a flow
|
||||||
|
@ -2,7 +2,6 @@ import urwid
|
|||||||
|
|
||||||
from mitmproxy.tools.console import common
|
from mitmproxy.tools.console import common
|
||||||
from mitmproxy.tools.console import signals
|
from mitmproxy.tools.console import signals
|
||||||
from mitmproxy.addons import view
|
|
||||||
import mitmproxy.tools.console.master # noqa
|
import mitmproxy.tools.console.master # noqa
|
||||||
|
|
||||||
|
|
||||||
@ -190,62 +189,6 @@ class FlowListBox(urwid.ListBox):
|
|||||||
self.master = master # type: "mitmproxy.tools.console.master.ConsoleMaster"
|
self.master = master # type: "mitmproxy.tools.console.master.ConsoleMaster"
|
||||||
super().__init__(FlowListWalker(master))
|
super().__init__(FlowListWalker(master))
|
||||||
|
|
||||||
def get_method_raw(self, k):
|
|
||||||
if k:
|
|
||||||
self.get_url(k)
|
|
||||||
|
|
||||||
def get_method(self, k):
|
|
||||||
if k == "e":
|
|
||||||
signals.status_prompt.send(
|
|
||||||
self,
|
|
||||||
prompt = "Method",
|
|
||||||
text = "",
|
|
||||||
callback = self.get_method_raw
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
method = ""
|
|
||||||
for i in common.METHOD_OPTIONS:
|
|
||||||
if i[1] == k:
|
|
||||||
method = i[0].upper()
|
|
||||||
self.get_url(method)
|
|
||||||
|
|
||||||
def get_url(self, method):
|
|
||||||
signals.status_prompt.send(
|
|
||||||
prompt = "URL",
|
|
||||||
text = "http://www.example.com/",
|
|
||||||
callback = self.new_request,
|
|
||||||
args = (method,)
|
|
||||||
)
|
|
||||||
|
|
||||||
def new_request(self, url, method):
|
|
||||||
try:
|
|
||||||
f = self.master.create_request(method, url)
|
|
||||||
except ValueError as e:
|
|
||||||
signals.status_message.send(message = "Invalid URL: " + str(e))
|
|
||||||
return
|
|
||||||
self.master.view.focus.flow = f
|
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
key = common.shortcuts(key)
|
key = common.shortcuts(key)
|
||||||
if key == "M":
|
|
||||||
self.master.view.toggle_marked()
|
|
||||||
elif key == "n":
|
|
||||||
signals.status_prompt_onekey.send(
|
|
||||||
prompt = "Method",
|
|
||||||
keys = common.METHOD_OPTIONS,
|
|
||||||
callback = self.get_method
|
|
||||||
)
|
|
||||||
elif key == "o":
|
|
||||||
orders = [(i[1], i[0]) for i in view.orders]
|
|
||||||
lookup = dict([(i[0], i[1]) for i in view.orders])
|
|
||||||
|
|
||||||
def change_order(k):
|
|
||||||
self.master.options.console_order = lookup[k]
|
|
||||||
|
|
||||||
signals.status_prompt_onekey.send(
|
|
||||||
prompt = "Order",
|
|
||||||
keys = orders,
|
|
||||||
callback = change_order
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return urwid.ListBox.keypress(self, size, key)
|
return urwid.ListBox.keypress(self, size, key)
|
||||||
|
@ -189,6 +189,18 @@ def default_keymap(km):
|
|||||||
km.add("l", "console.command cut.clip ", context="flowlist")
|
km.add("l", "console.command cut.clip ", context="flowlist")
|
||||||
km.add("L", "console.command view.load ", context="flowlist")
|
km.add("L", "console.command view.load ", context="flowlist")
|
||||||
km.add("m", "flow.mark.toggle @focus", context="flowlist")
|
km.add("m", "flow.mark.toggle @focus", context="flowlist")
|
||||||
|
km.add("M", "view.marked.toggle", context="flowlist")
|
||||||
|
km.add(
|
||||||
|
"n",
|
||||||
|
"console.command view.create get https://google.com",
|
||||||
|
context="flowlist"
|
||||||
|
)
|
||||||
|
km.add(
|
||||||
|
"o",
|
||||||
|
"console.choose Order view.order.options "
|
||||||
|
"set console_order={choice}",
|
||||||
|
context="flowlist"
|
||||||
|
)
|
||||||
km.add("r", "replay.client @focus", context="flowlist")
|
km.add("r", "replay.client @focus", context="flowlist")
|
||||||
km.add("S", "console.command 'replay.server '")
|
km.add("S", "console.command 'replay.server '")
|
||||||
km.add("v", "set console_order_reversed=toggle", context="flowlist")
|
km.add("v", "set console_order_reversed=toggle", context="flowlist")
|
||||||
|
@ -137,6 +137,22 @@ def tdump(path, flows):
|
|||||||
w.add(i)
|
w.add(i)
|
||||||
|
|
||||||
|
|
||||||
|
def test_create():
|
||||||
|
v = view.View()
|
||||||
|
with taddons.context():
|
||||||
|
v.create("get", "http://foo.com")
|
||||||
|
assert len(v) == 1
|
||||||
|
assert v[0].request.url == "http://foo.com/"
|
||||||
|
v.create("get", "http://foo.com")
|
||||||
|
assert len(v) == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_orders():
|
||||||
|
v = view.View()
|
||||||
|
with taddons.context():
|
||||||
|
assert v.order_options()
|
||||||
|
|
||||||
|
|
||||||
def test_load(tmpdir):
|
def test_load(tmpdir):
|
||||||
path = str(tmpdir.join("path"))
|
path = str(tmpdir.join("path"))
|
||||||
v = view.View()
|
v = view.View()
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
from unittest import mock
|
|
||||||
import urwid
|
import urwid
|
||||||
|
|
||||||
import mitmproxy.tools.console.flowlist as flowlist
|
import mitmproxy.tools.console.flowlist as flowlist
|
||||||
@ -14,13 +13,6 @@ class TestFlowlist:
|
|||||||
o = options.Options(**opts)
|
o = options.Options(**opts)
|
||||||
return console.master.ConsoleMaster(o, proxy.DummyServer())
|
return console.master.ConsoleMaster(o, proxy.DummyServer())
|
||||||
|
|
||||||
def test_new_request(self):
|
|
||||||
m = self.mkmaster()
|
|
||||||
x = flowlist.FlowListBox(m)
|
|
||||||
with mock.patch('mitmproxy.tools.console.signals.status_message.send') as mock_thing:
|
|
||||||
x.new_request("nonexistent url", "GET")
|
|
||||||
mock_thing.assert_called_once_with(message="Invalid URL: No hostname given")
|
|
||||||
|
|
||||||
def test_logbuffer_set_focus(self):
|
def test_logbuffer_set_focus(self):
|
||||||
m = self.mkmaster()
|
m = self.mkmaster()
|
||||||
b = flowlist.LogBufferBox(m)
|
b = flowlist.LogBufferBox(m)
|
||||||
|
@ -113,10 +113,6 @@ class TestFlowMaster:
|
|||||||
with pytest.raises(Exception, match="live"):
|
with pytest.raises(Exception, match="live"):
|
||||||
fm.replay_request(f)
|
fm.replay_request(f)
|
||||||
|
|
||||||
def test_create_flow(self):
|
|
||||||
fm = master.Master(None, DummyServer())
|
|
||||||
assert fm.create_request("GET", "http://example.com/")
|
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
s = tservers.TestState()
|
s = tservers.TestState()
|
||||||
fm = master.Master(None, DummyServer())
|
fm = master.Master(None, DummyServer())
|
||||||
|
Loading…
Reference in New Issue
Block a user