aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/tools/main.py
blob: 7b2d2a7b912c9357f982367a7d6b06cb8dbacf05 (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
from __future__ import print_function  # this is here for the version check to work on Python 2.
import sys

if sys.version_info < (3, 5):
    print("#" * 49, file=sys.stderr)
    print("# mitmproxy only supports Python 3.5 and above! #", file=sys.stderr)
    print("#" * 49, file=sys.stderr)

import os  # noqa
import signal  # noqa

from mitmproxy.tools import cmdline  # noqa
from mitmproxy import exceptions  # noqa
from mitmproxy import options  # noqa
from mitmproxy import optmanager  # noqa
from mitmproxy.proxy import config  # noqa
from mitmproxy.proxy import server  # noqa
from mitmproxy.utils import version_check  # noqa
from mitmproxy.utils import debug  # noqa


def assert_utf8_env():
    spec = ""
    for i in ["LANG", "LC_CTYPE", "LC_ALL"]:
        spec += os.environ.get(i, "").lower()
    if "utf" not in spec:
        print(
            "Error: mitmproxy requires a UTF console environment.",
            file=sys.stderr
        )
        print(
            "Set your LANG enviroment variable to something like en_US.UTF-8",
            file=sys.stderr
        )
        sys.exit(1)


def process_options(parser, opts, args):
    if args.version:
        print(debug.dump_system_info())
        sys.exit(0)
    if args.options:
        print(optmanager.dump(opts))
        sys.exit(0)
    if args.quiet:
        args.flow_detail = 0

    adict = {}
    for n in dir(args):
        if n in opts:
            adict[n] = getattr(args, n)
    opts.merge(adict)

    pconf = config.ProxyConfig(opts)
    if opts.server:
        try:
            return server.ProxyServer(pconf)
        except exceptions.ServerException as v:
            print(str(v), file=sys.stderr)
            sys.exit(1)
    else:
        return server.DummyServer(pconf)


def run(MasterKlass, args):  # pragma: no cover
    version_check.check_pyopenssl_version()
    debug.register_info_dumpers()

    opts = options.Options()
    parser = cmdline.mitmdump(opts)
    args = parser.parse_args(args)
    master = None
    try:
        opts.load_paths(args.conf)
        server = process_options(parser, opts, args)
        master = MasterKlass(opts, server)
        master.addons.configure_all(opts, opts.keys())
        opts.set(*args.setoptions)

        def cleankill(*args, **kwargs):
            master.shutdown()

        signal.signal(signal.SIGTERM, cleankill)
        master.run()
    except exceptions.OptionsError as e:
        print("%s: %s" % (sys.argv[0], e), file=sys.stderr)
        sys.exit(1)
    except (KeyboardInterrupt, RuntimeError):
        pass
    if master is None or getattr(master, "has_errored", None):
        print("%s: errors occurred during run" % sys.argv[0], file=sys.stderr)
        sys.exit(1)


def mitmproxy(args=None):  # pragma: no cover
    if os.name == "nt":
        print("Error: mitmproxy's console interface is not supported on Windows. "
              "You can run mitmdump or mitmweb instead.", file=sys.stderr)
        sys.exit(1)
    assert_utf8_env()

    from mitmproxy.tools import console
    run(console.master.ConsoleMaster, args)


def mitmdump(args=None):  # pragma: no cover
    from mitmproxy.tools import dump
    run(dump.DumpMaster, args)


def mitmweb(args=None):  # pragma: no cover
    from mitmproxy.tools import web
    run(web.master.WebMaster, args)