Exemple #1
0
    def console_choose_cmd(
        self,
        prompt: str,
        choicecmd: mitmproxy.types.Cmd,
        subcmd: mitmproxy.types.Cmd,
        *args: mitmproxy.types.Arg
    ) -> None:
        """
            Prompt the user to choose from a list of strings returned by a
            command, then invoke another command with all occurrences of {choice}
            replaced by the choice the user made.
        """
        choices = ctx.master.commands.call_strings(choicecmd, [])

        def callback(opt):
            # We're now outside of the call context...
            repl = shlex.quote(" ".join(args))
            repl = repl.replace("{choice}", opt)
            try:
                self.master.commands.call(subcmd + " " + repl)
            except exceptions.CommandError as e:
                signals.status_message.send(message=str(e))

        self.master.overlay(
            overlay.Chooser(self.master, prompt, choices, "", callback)
        )
Exemple #2
0
    def console_choose_cmd(
            self,
            prompt: str,
            choicecmd: mitmproxy.types.Cmd,
            subcmd: mitmproxy.types.Cmd,
            *args: mitmproxy.types.CmdArgs
    ) -> None:
        """
            Prompt the user to choose from a list of strings returned by a
            command, then invoke another command with all occurrences of {choice}
            replaced by the choice the user made.
        """
        choices = ctx.master.commands.execute(choicecmd)

        def callback(opt):
            # We're now outside of the call context...
            repl = [arg.replace("{choice}", opt) for arg in args]
            try:
                self.master.commands.call_strings(subcmd, repl)
            except exceptions.CommandError as e:
                ctx.log.error(str(e))

        self.master.overlay(
            overlay.Chooser(self.master, prompt, choices, "", callback)
        )
Exemple #3
0
    def list_flows(self) -> None:
        """
            Show server responses list.
        """
        recorded_flows = []
        for flows in _find_addon().flowmap.values():
            for f in flows:
                recorded_flows.append(f)

        if len(recorded_flows) == 0:
            ctx.log.alert("No flows.")
            return

        choices = []
        for flow in recorded_flows:
            c = FlowChoice(flow.request.url)
            c.flow = flow
            choices.append(c)

        def callback(opt):
            if opt.flow not in ctx.master.view:
                ctx.log.alert("Not found.")
            else:
                ctx.master.view.focus.flow = opt.flow

        ctx.master.overlay(
            overlay.Chooser(ctx.master, "Flows", choices, "", callback))
Exemple #4
0
 def keypress(self, size, key):
     if self.walker.editing:
         if key == "enter":
             foc, idx = self.get_focus()
             v = self.walker.get_edit_text()
             try:
                 d = self.master.options.parse_setval(foc.opt, v)
                 self.master.options.update(**{foc.opt.name: d})
             except exceptions.OptionsError as v:
                 signals.status_message.send(message=str(v))
             self.walker.stop_editing()
             return None
         elif key == "esc":
             self.walker.stop_editing()
             return None
     else:
         if key == "m_start":
             self.set_focus(0)
             self.walker._modified()
         elif key == "m_end":
             self.set_focus(len(self.walker.opts) - 1)
             self.walker._modified()
         elif key == "m_select":
             foc, idx = self.get_focus()
             if foc.opt.typespec == bool:
                 self.master.options.toggler(foc.opt.name)()
                 # Bust the focus widget cache
                 self.set_focus(self.walker.index)
             elif can_edit_inplace(foc.opt):
                 self.walker.start_editing()
                 self.walker._modified()
             elif foc.opt.choices:
                 self.master.overlay(
                     overlay.Chooser(
                         self.master,
                         foc.opt.name,
                         foc.opt.choices,
                         foc.opt.current(),
                         self.master.options.setter(foc.opt.name)
                     )
                 )
             elif foc.opt.typespec == Sequence[str]:
                 self.master.overlay(
                     overlay.OptionsOverlay(
                         self.master,
                         foc.opt.name,
                         foc.opt.current(),
                         HELP_HEIGHT + 5
                     ),
                     valign="top"
                 )
             else:
                 raise NotImplementedError()
     return super().keypress(size, key)
Exemple #5
0
    def console_choose(self, prompt: str, choices: typing.Sequence[str],
                       cmd: mitmproxy.types.Cmd,
                       *args: mitmproxy.types.CmdArgs) -> None:
        """
            Prompt the user to choose from a specified list of strings, then
            invoke another command with all occurrences of {choice} replaced by
            the choice the user made.
        """
        def callback(opt):
            # We're now outside of the call context...
            repl = [arg.replace("{choice}", opt) for arg in args]
            try:
                self.master.commands.call_strings(cmd, repl)
            except exceptions.CommandError as e:
                ctx.log.error(str(e))

        self.master.overlay(
            overlay.Chooser(self.master, prompt, choices, "", callback))
Exemple #6
0
    def console_choose(self, prompt: str, choices: typing.Sequence[str],
                       *cmd: str) -> None:
        """
            Prompt the user to choose from a specified list of strings, then
            invoke another command with all occurances of {choice} replaced by
            the choice the user made.
        """
        def callback(opt):
            # We're now outside of the call context...
            repl = " ".join(cmd)
            repl = repl.replace("{choice}", opt)
            try:
                self.master.commands.call(repl)
            except exceptions.CommandError as e:
                signals.status_message.send(message=str(e))

        self.master.overlay(
            overlay.Chooser(self.master, prompt, choices, "", callback))
    def list(self):
        """
            Show added matchers
        """
        if len(self.matchermap) == 0:
            ctx.log.alert("No matchers")
            return

        choices = []
        for (key, matcher) in self.matchermap.items():
            choices.append("%s | %s | %s" % (key, matcher.code, matcher.path))

        def callback(opt):
            pass

        ctx.master.overlay(
            overlay.Chooser(ctx.master, "Matchers", choices, "", callback)
        )
    def flowview_mode_set(self) -> None:
        """
            Set the display mode for the current flow view.
        """
        fv = self.master.window.current("flowview")
        if not fv:
            raise exceptions.CommandError("Not viewing a flow.")
        idx = fv.body.tab_offset

        def callback(opt):
            try:
                self.master.commands.call_args(
                    "view.setval",
                    ["@focus", "flowview_mode_%s" % idx, opt]
                )
            except exceptions.CommandError as e:
                signals.status_message.send(message=str(e))

        opts = [i.name.lower() for i in contentviews.views]
        self.master.overlay(overlay.Chooser(self.master, "Mode", opts, "", callback))
Exemple #9
0
    def keypress(self, size, key):
        conn = None  # type: Optional[Union[http.HTTPRequest, http.HTTPResponse]]
        if self.tab_offset == TAB_REQ:
            conn = self.flow.request
        elif self.tab_offset == TAB_RESP:
            conn = self.flow.response

        key = super().keypress(size, key)

        # Special case: Space moves over to the next flow.
        # We need to catch that before applying common.shortcuts()
        if key == " ":
            self.view_next_flow(self.flow)
            return

        key = common.shortcuts(key)
        if key in ("up", "down", "page up", "page down"):
            # Pass scroll events to the wrapped widget
            self._w.keypress(size, key)
        elif key == "a":
            self.flow.resume()
            self.master.view.update(self.flow)
        elif key == "A":
            for f in self.view:
                if f.intercepted:
                    f.resume()
                    self.master.view.update(self.flow)
        elif key == "d":
            if self.flow.killable:
                self.flow.kill()
            self.view.remove(self.flow)
            if not self.view.focus.flow:
                self.master.view_flowlist()
            else:
                self.view_flow(self.view.focus.flow)
        elif key == "D":
            cp = self.flow.copy()
            self.master.view.add(cp)
            self.master.view.focus.flow = cp
            self.view_flow(cp)
            signals.status_message.send(message="Duplicated.")
        elif key == "p":
            self.view_prev_flow(self.flow)
        elif key == "r":
            try:
                self.master.replay_request(self.flow)
            except exceptions.ReplayException as e:
                signals.add_log("Replay error: %s" % e, "warn")
            signals.flow_change.send(self, flow=self.flow)
        elif key == "V":
            if self.flow.modified():
                self.flow.revert()
                signals.flow_change.send(self, flow=self.flow)
                signals.status_message.send(message="Reverted.")
            else:
                signals.status_message.send(message="Flow not modified.")
        elif key == "W":
            signals.status_prompt_path.send(prompt="Save this flow",
                                            callback=self.master.save_one_flow,
                                            args=(self.flow, ))
        elif key == "|":
            signals.status_prompt_path.send(
                prompt="Send flow to script",
                callback=self.master.run_script_once,
                args=(self.flow, ))
        elif key == "e":
            if self.tab_offset == TAB_REQ:
                signals.status_prompt_onekey.send(prompt="Edit request",
                                                  keys=(
                                                      ("cookies", "c"),
                                                      ("query", "q"),
                                                      ("path", "p"),
                                                      ("url", "u"),
                                                      ("header", "h"),
                                                      ("form", "f"),
                                                      ("raw body", "r"),
                                                      ("method", "m"),
                                                  ),
                                                  callback=self.edit)
            elif self.tab_offset == TAB_RESP:
                signals.status_prompt_onekey.send(prompt="Edit response",
                                                  keys=(
                                                      ("cookies", "c"),
                                                      ("code", "o"),
                                                      ("message", "m"),
                                                      ("header", "h"),
                                                      ("raw body", "r"),
                                                  ),
                                                  callback=self.edit)
            else:
                signals.status_message.send(
                    message="Tab to the request or response", expire=1)
        elif key in set("bfgmxvzEC") and not conn:
            signals.status_message.send(
                message="Tab to the request or response", expire=1)
            return
        elif key == "b":
            if self.tab_offset == TAB_REQ:
                common.ask_save_body("q", self.flow)
            else:
                common.ask_save_body("s", self.flow)
        elif key == "f":
            self.view.settings[self.flow][(self.tab_offset,
                                           "fullcontents")] = True
            signals.flow_change.send(self, flow=self.flow)
            signals.status_message.send(message="Loading all body data...")
        elif key == "m":
            opts = [i.name.lower() for i in contentviews.views]
            self.master.overlay(
                overlay.Chooser("display mode", opts, self.viewmode_get(),
                                self.change_this_display_mode))
        elif key == "E":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt="Export to file",
                keys=[(e[0], e[1]) for e in export.EXPORTERS],
                callback=common.export_to_clip_or_file,
                args=(scope, self.flow, common.ask_save_path))
        elif key == "C":
            if self.tab_offset == TAB_REQ:
                scope = "q"
            else:
                scope = "s"
            signals.status_prompt_onekey.send(
                self,
                prompt="Export to clipboard",
                keys=[(e[0], e[1]) for e in export.EXPORTERS],
                callback=common.export_to_clip_or_file,
                args=(scope, self.flow, common.copy_to_clipboard_or_prompt))
        elif key == "x":
            conn.content = None
            signals.flow_change.send(self, flow=self.flow)
        elif key == "v":
            if conn.raw_content:
                t = conn.headers.get("content-type")
                if "EDITOR" in os.environ or "PAGER" in os.environ:
                    self.master.spawn_external_viewer(
                        conn.get_content(strict=False), t)
                else:
                    signals.status_message.send(
                        message="Error! Set $EDITOR or $PAGER.")
        elif key == "z":
            self.flow.backup()
            e = conn.headers.get("content-encoding", "identity")
            if e != "identity":
                try:
                    conn.decode()
                except ValueError:
                    signals.status_message.send(
                        message="Could not decode - invalid data?")
            else:
                signals.status_prompt_onekey.send(
                    prompt="Select encoding: ",
                    keys=(
                        ("gzip", "z"),
                        ("deflate", "d"),
                        ("brotli", "b"),
                    ),
                    callback=self.encode_callback,
                    args=(conn, ))
            signals.flow_change.send(self, flow=self.flow)
        else:
            # Key is not handled here.
            return key