aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/tools/console/window.py
blob: d7038da00958d4be684256f7d908b83d04e0cb3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import urwid
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import statusbar
from mitmproxy.tools.console import flowlist
from mitmproxy.tools.console import flowview
from mitmproxy.tools.console import commands
from mitmproxy.tools.console import options
from mitmproxy.tools.console import overlay
from mitmproxy.tools.console import help
from mitmproxy.tools.console import grideditor


class Window(urwid.Frame):
    def __init__(self, master):
        self.statusbar = statusbar.StatusBar(master, "")
        super().__init__(
            None,
            header = None,
            footer = urwid.AttrWrap(self.statusbar, "background")
        )
        self.master = master
        self.primary_stack = []
        self.master.view.sig_view_refresh.connect(self.view_changed)
        self.master.view.sig_view_add.connect(self.view_changed)
        self.master.view.sig_view_remove.connect(self.view_changed)
        self.master.view.sig_view_update.connect(self.view_changed)
        self.master.view.focus.sig_change.connect(self.view_changed)
        signals.focus.connect(self.sig_focus)

        self.master.view.focus.sig_change.connect(self.focus_changed)
        signals.flow_change.connect(self.flow_changed)

        signals.pop_view_state.connect(self.pop)
        signals.push_view_state.connect(self.push)
        self.windows = dict(
            flowlist = flowlist.FlowListBox(self.master),
            flowview = flowview.FlowView(self.master),
            commands = commands.Commands(self.master),
            options = options.Options(self.master),
            help = help.HelpView(None),
            edit_focus_query = grideditor.QueryEditor(self.master),
            edit_focus_cookies = grideditor.CookieEditor(self.master),
            edit_focus_setcookies = grideditor.SetCookieEditor(self.master),
            edit_focus_form = grideditor.RequestFormEditor(self.master),
            edit_focus_path = grideditor.PathEditor(self.master),
            edit_focus_request_headers = grideditor.RequestHeaderEditor(self.master),
            edit_focus_response_headers = grideditor.ResponseHeaderEditor(self.master),
        )

    def call(self, v, name, *args, **kwargs):
        f = getattr(v, name, None)
        if f:
            f(*args, **kwargs)

    def flow_changed(self, sender, flow):
        if self.master.view.focus.flow:
            if flow.id == self.master.view.focus.flow.id:
                self.focus_changed()

    def focus_changed(self, *args, **kwargs):
        """
            Triggered when the focus changes - either when it's modified, or
            when it changes to a different flow altogether.
        """
        self.call(self.focus, "focus_changed")

    def view_changed(self, *args, **kwargs):
        """
            Triggered when the view list has changed.
        """
        self.call(self.focus, "view_changed")

    def view_popping(self, *args, **kwargs):
        """
            Triggered when the view list has changed.
        """
        self.call(self.focus, "view_popping")

    def push(self, wname):
        if self.primary_stack and self.primary_stack[-1] == wname:
            return
        self.primary_stack.append(wname)
        self.body = urwid.AttrWrap(
            self.windows[wname], "background"
        )
        self.view_changed()
        self.focus_changed()

    def pop(self, *args, **kwargs):
        if isinstance(self.master.loop.widget, overlay.SimpleOverlay):
            self.master.loop.widget = self
        else:
            if len(self.primary_stack) > 1:
                self.view_popping()
                self.primary_stack.pop()
                self.body = urwid.AttrWrap(
                    self.windows[self.primary_stack[-1]],
                    "background",
                )
                self.view_changed()
                self.focus_changed()
            else:
                self.master.prompt_for_exit()

    def sig_focus(self, sender, section):
        self.focus_position = section

    def mouse_event(self, *args, **kwargs):
        # args: (size, event, button, col, row)
        k = super().mouse_event(*args, **kwargs)
        if not k:
            if args[1] == "mouse drag":
                signals.status_message.send(
                    message = "Hold down fn, shift, alt or ctrl to select text or use the --no-mouse parameter.",
                    expire = 1
                )
            elif args[1] == "mouse press" and args[2] == 4:
                self.keypress(args[0], "up")
            elif args[1] == "mouse press" and args[2] == 5:
                self.keypress(args[0], "down")
            else:
                return False
            return True

    def keypress(self, size, k):
        if self.focus.keyctx:
            k = self.master.keymap.handle(self.focus.keyctx, k)
        if k:
            return super().keypress(size, k)