Exemple #1
0
    def run(self):
        self.ui = urwid.raw_display.Screen()
        self.ui.set_terminal_properties(256)
        self.set_palette(self.palette)
        self.loop = urwid.MainLoop(
            urwid.SolidFill("x"),
            screen = self.ui,
            handle_mouse = not self.options.no_mouse,
        )

        if self.options.rfile:
            ret = self.load_flows_path(self.options.rfile)
            if ret and self.state.flow_count():
                signals.add_event(
                    "File truncated or corrupted. "
                    "Loaded as many flows as possible.",
                    "error"
                )
            elif ret and not self.state.flow_count():
                self.shutdown()
                print("Could not load file: {}".format(ret), file=sys.stderr)
                sys.exit(1)

        self.loop.set_alarm_in(0.01, self.ticker)
        if self.server.config.http2 and not tcp.HAS_ALPN:  # pragma: no cover
            def http2err(*args, **kwargs):
                signals.status_message.send(
                    message = "HTTP/2 disabled - OpenSSL 1.0.2+ required."
                              " Use --no-http2 to silence this warning.",
                    expire=5
                )
            self.loop.set_alarm_in(0.01, http2err)

        # It's not clear why we need to handle this explicitly - without this,
        # mitmproxy hangs on keyboard interrupt. Remove if we ever figure it
        # out.
        def exit(s, f):
            raise urwid.ExitMainLoop
        signal.signal(signal.SIGINT, exit)

        self.loop.set_alarm_in(
            0.0001,
            lambda *args: self.view_flowlist()
        )

        self.start()
        try:
            self.loop.run()
        except Exception:
            self.loop.stop()
            sys.stdout.flush()
            print(traceback.format_exc(), file=sys.stderr)
            print("mitmproxy has crashed!", file=sys.stderr)
            print("Please lodge a bug report at:", file=sys.stderr)
            print("\thttps://github.com/mitmproxy/mitmproxy", file=sys.stderr)
            print("Shutting down...", file=sys.stderr)
        sys.stderr.flush()
        self.shutdown()
Exemple #2
0
    def _get_content_view(self, viewmode, message, max_lines, _):

        try:
            query = None
            if isinstance(message, models.HTTPRequest):
                query = message.query
            description, lines = contentviews.get_content_view(
                viewmode,
                message.content,
                headers=message.headers,
                query=query)
        except exceptions.ContentViewException:
            s = "Content viewer failed: \n" + traceback.format_exc()
            signals.add_event(s, "error")
            description, lines = contentviews.get_content_view(
                contentviews.get("Raw"),
                message.content,
                headers=message.headers)
            description = description.replace(
                "Raw", "Couldn't parse: falling back to Raw")

        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message,
                                                      models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(
                math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(
                    urwid.Text([
                        ("highlight",
                         "Stopped displaying data after %d lines. Press " %
                         max_lines), ("key", "f"),
                        ("highlight", " to load all data.")
                    ]))
                break

        return description, text_objects
Exemple #3
0
 def _run_script_method(self, method, s, f):
     status, val = s.run(method, f)
     if val:
         if status:
             signals.add_event("Method %s return: %s" % (method, val), "debug")
         else:
             signals.add_event(
                 "Method %s error: %s" %
                 (method, val[1]), "error")
Exemple #4
0
 def _run_script_method(self, method, s, f):
     status, val = s.run(method, f)
     if val:
         if status:
             signals.add_event("Method %s return: %s" % (method, val),
                               "debug")
         else:
             signals.add_event("Method %s error: %s" % (method, val[1]),
                               "error")
Exemple #5
0
    def run(self):
        self.ui = urwid.raw_display.Screen()
        self.ui.set_terminal_properties(256)
        self.set_palette(self.palette)
        self.loop = urwid.MainLoop(
            urwid.SolidFill("x"),
            screen=self.ui,
            handle_mouse=not self.options.no_mouse,
        )

        if self.options.rfile:
            ret = self.load_flows_path(self.options.rfile)
            if ret and self.state.flow_count():
                signals.add_event(
                    "File truncated or corrupted. "
                    "Loaded as many flows as possible.", "error")
            elif ret and not self.state.flow_count():
                self.shutdown()
                print("Could not load file: {}".format(ret), file=sys.stderr)
                sys.exit(1)

        self.loop.set_alarm_in(0.01, self.ticker)
        if self.server.config.http2 and not tcp.HAS_ALPN:  # pragma: no cover

            def http2err(*args, **kwargs):
                signals.status_message.send(
                    message="HTTP/2 disabled - OpenSSL 1.0.2+ required."
                    " Use --no-http2 to silence this warning.",
                    expire=5)

            self.loop.set_alarm_in(0.01, http2err)

        # It's not clear why we need to handle this explicitly - without this,
        # mitmproxy hangs on keyboard interrupt. Remove if we ever figure it
        # out.
        def exit(s, f):
            raise urwid.ExitMainLoop

        signal.signal(signal.SIGINT, exit)

        self.loop.set_alarm_in(0.0001, lambda *args: self.view_flowlist())

        self.start()
        try:
            self.loop.run()
        except Exception:
            self.loop.stop()
            sys.stdout.flush()
            print(traceback.format_exc(), file=sys.stderr)
            print("mitmproxy has crashed!", file=sys.stderr)
            print("Please lodge a bug report at:", file=sys.stderr)
            print("\thttps://github.com/mitmproxy/mitmproxy", file=sys.stderr)
            print("Shutting down...", file=sys.stderr)
        sys.stderr.flush()
        self.shutdown()
Exemple #6
0
    def _get_content_view(self, viewmode, message, max_lines, _):

        try:
            query = None
            if isinstance(message, models.HTTPRequest):
                query = message.query
            description, lines = contentviews.get_content_view(
                viewmode, message.content, headers=message.headers, query=query
            )
        except exceptions.ContentViewException:
            s = "Content viewer failed: \n" + traceback.format_exc()
            signals.add_event(s, "error")
            description, lines = contentviews.get_content_view(
                contentviews.get("Raw"), message.content, headers=message.headers
            )
            description = description.replace("Raw", "Couldn't parse: falling back to Raw")

        # Give hint that you have to tab for the response.
        if description == "No content" and isinstance(message, models.HTTPRequest):
            description = "No request content (press tab to view response)"

        # If the users has a wide terminal, he gets fewer lines; this should not be an issue.
        chars_per_line = 80
        max_chars = max_lines * chars_per_line
        total_chars = 0
        text_objects = []
        for line in lines:
            txt = []
            for (style, text) in line:
                if total_chars + len(text) > max_chars:
                    text = text[:max_chars - total_chars]
                txt.append((style, text))
                total_chars += len(text)
                if total_chars == max_chars:
                    break

            # round up to the next line.
            total_chars = int(math.ceil(total_chars / chars_per_line) * chars_per_line)

            text_objects.append(urwid.Text(txt))
            if total_chars == max_chars:
                text_objects.append(urwid.Text([
                    ("highlight", "Stopped displaying data after %d lines. Press " % max_lines),
                    ("key", "f"),
                    ("highlight", " to load all data.")
                ]))
                break

        return description, text_objects
Exemple #7
0
    def edit_scripts(self, scripts):
        commands = [x[0] for x in scripts]  # remove outer array
        if commands == [s.command for s in self.scripts]:
            return

        self.unload_scripts()
        for command in commands:
            try:
                self.load_script(command)
            except exceptions.ScriptException as e:
                signals.status_message.send(
                    message='Error loading "{}".'.format(command)
                )
                signals.add_event('Error loading "{}":\n{}'.format(command, e), "error")
        signals.update_settings.send(self)
Exemple #8
0
    def edit_scripts(self, scripts):
        commands = [x[0] for x in scripts]  # remove outer array
        if commands == [s.command for s in self.scripts]:
            return

        self.unload_scripts()
        for command in commands:
            try:
                self.load_script(command)
            except exceptions.ScriptException as e:
                signals.status_message.send(
                    message='Error loading "{}".'.format(command))
                signals.add_event('Error loading "{}":\n{}'.format(command, e),
                                  "error")
        signals.update_settings.send(self)
Exemple #9
0
    def run_script_once(self, command, f):
        if not command:
            return
        signals.add_event("Running script on flow: %s" % command, "debug")

        try:
            s = script.Script(command)
            s.load()
        except script.ScriptException as e:
            signals.status_message.send(
                message='Error loading "{}".'.format(command)
            )
            signals.add_event('Error loading "{}":\n{}'.format(command, e), "error")
            return

        if f.request:
            self._run_script_method("request", s, f)
        if f.response:
            self._run_script_method("response", s, f)
        if f.error:
            self._run_script_method("error", s, f)
        s.unload()
        signals.flow_change.send(self, flow = f)
Exemple #10
0
    def run_script_once(self, command, f):
        if not command:
            return
        signals.add_event("Running script on flow: %s" % command, "debug")

        try:
            s = script.Script(command, script.ScriptContext(self))
            s.load()
        except script.ScriptException as e:
            signals.status_message.send(
                message='Error loading "{}".'.format(command))
            signals.add_event('Error loading "{}":\n{}'.format(command, e),
                              "error")
            return

        if f.request:
            self._run_script_method("request", s, f)
        if f.response:
            self._run_script_method("response", s, f)
        if f.error:
            self._run_script_method("error", s, f)
        s.unload()
        signals.flow_change.send(self, flow=f)
Exemple #11
0
 def add_event(self, e, level):
     signals.add_event(e, level)
Exemple #12
0
 def add_event(self, e, level):
     signals.add_event(e, level)