diff --git a/libmproxy/app.py b/libmproxy/app.py index 24187704a..697210318 100644 --- a/libmproxy/app.py +++ b/libmproxy/app.py @@ -17,12 +17,12 @@ def index(): @mapp.route("/cert/pem") def certs_pem(): - p = os.path.join(master().server.config.confdir, proxy.CONF_BASENAME + "-ca-cert.pem") + p = os.path.join(master().server.config.confdir, proxy.config.CONF_BASENAME + "-ca-cert.pem") return flask.Response(open(p, "rb").read(), mimetype='application/x-x509-ca-cert') @mapp.route("/cert/p12") def certs_p12(): - p = os.path.join(master().server.config.confdir, proxy.CONF_BASENAME + "-ca-cert.p12") + p = os.path.join(master().server.config.confdir, proxy.config.CONF_BASENAME + "-ca-cert.p12") return flask.Response(open(p, "rb").read(), mimetype='application/x-pkcs12') diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py index 7950d40b8..72c137698 100644 --- a/libmproxy/cmdline.py +++ b/libmproxy/cmdline.py @@ -1,4 +1,4 @@ -import proxy +from . import proxy import re, filt import argparse @@ -387,4 +387,4 @@ def common_options(parser): help="Allow access to users specified in an Apache htpasswd file." ) - proxy.ssl_option_group(parser) + proxy.config.ssl_option_group(parser) diff --git a/libmproxy/flow.py b/libmproxy/flow.py index c362465ca..452fd783e 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -7,13 +7,15 @@ import hashlib, Cookie, cookielib, re, threading import os import flask import requests +from . import controller, protocol +from .protocol import http +from .proxy.connection import ServerConnection +from .proxy.primitives import ProxyError import tnetstring, filt, script -from netlib import odict, wsgi -import controller, version, protocol +from netlib import odict, wsgi, tcp +import netlib.http +import version import app -from .protocol import KILL -from .protocol.http import HTTPResponse, CONTENT_MISSING -from .proxy import RequestReplayThread ODict = odict.ODict ODictCaseless = odict.ODictCaseless @@ -564,7 +566,7 @@ class FlowMaster(controller.Master): rflow = self.server_playback.next_flow(flow) if not rflow: return None - response = HTTPResponse._from_state(rflow.response._get_state()) + response = http.HTTPResponse._from_state(rflow.response._get_state()) response.is_replay = True if self.refresh_server_playback: response.refresh() @@ -641,7 +643,7 @@ class FlowMaster(controller.Master): """ if f.intercepting: return "Can't replay while intercepting..." - if f.request.content == CONTENT_MISSING: + if f.request.content == http.CONTENT_MISSING: return "Can't replay request with missing content..." if f.request: f.request.is_replay = True @@ -692,7 +694,7 @@ class FlowMaster(controller.Master): err = app.serve(r, r.flow.client_conn.wfile, **{"mitmproxy.master": self}) if err: self.add_event("Error in wsgi app. %s"%err, "error") - r.reply(KILL) + r.reply(protocol.KILL) return f = self.state.add_request(r) self.replacehooks.run(f) @@ -784,3 +786,25 @@ class FilteredFlowWriter: d = f._get_state() tnetstring.dump(d, self.fo) + +class RequestReplayThread(threading.Thread): + name="RequestReplayThread" + + def __init__(self, config, flow, masterq): + self.config, self.flow, self.channel = config, flow, controller.Channel(masterq) + threading.Thread.__init__(self) + + def run(self): + try: + r = self.flow.request + server = ServerConnection(self.flow.server_conn.address(), None) + server.connect() + if self.flow.server_conn.ssl_established: + server.establish_ssl(self.config.clientcerts, + self.flow.server_conn.sni) + server.send(r._assemble()) + self.flow.response = http.HTTPResponse.from_stream(server.rfile, r.method, body_size_limit=self.config.body_size_limit) + self.channel.ask("response", self.flow.response) + except (ProxyError, netlib.http.HttpError, tcp.NetLibError), v: + self.flow.error = protocol.primitives.Error(str(v)) + self.channel.ask("error", self.flow.error) \ No newline at end of file diff --git a/libmproxy/protocol/__init__.py b/libmproxy/protocol/__init__.py index 392a8e3d7..6200757f8 100644 --- a/libmproxy/protocol/__init__.py +++ b/libmproxy/protocol/__init__.py @@ -1,4 +1,4 @@ -from ..prxy.server import AddressPriority +from libmproxy.proxy.primitives import AddressPriority KILL = 0 # const for killed requests diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index 3f9668ae4..77a09e614 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -1,8 +1,8 @@ import Cookie, urllib, urlparse, time, copy from email.utils import parsedate_tz, formatdate, mktime_tz -from ..prxy.connection import ServerConnection -from ..prxy.exception import ProxyError, ConnectionTypeChange -from ..prxy.server import AddressPriority +from libmproxy.proxy.primitives import AddressPriority +from ..proxy.connection import ServerConnection +from ..proxy.primitives import ProxyError, ConnectionTypeChange import netlib.utils from netlib import http, tcp, http_status from netlib.odict import ODict, ODictCaseless diff --git a/libmproxy/protocol/primitives.py b/libmproxy/protocol/primitives.py index 7cee074de..f27014587 100644 --- a/libmproxy/protocol/primitives.py +++ b/libmproxy/protocol/primitives.py @@ -1,5 +1,5 @@ from .. import stateobject, utils, version -from ..prxy.connection import ClientConnection, ServerConnection +from ..proxy.connection import ClientConnection, ServerConnection import copy diff --git a/libmproxy/prxy/__init__.py b/libmproxy/proxy/__init__.py similarity index 100% rename from libmproxy/prxy/__init__.py rename to libmproxy/proxy/__init__.py diff --git a/libmproxy/proxy/config.py b/libmproxy/proxy/config.py new file mode 100644 index 000000000..38c6ce890 --- /dev/null +++ b/libmproxy/proxy/config.py @@ -0,0 +1,124 @@ +import os +from .. import utils, platform +from netlib import http_auth, certutils + + +TRANSPARENT_SSL_PORTS = [443, 8443] +CONF_BASENAME = "mitmproxy" +CONF_DIR = "~/.mitmproxy" + + +class ProxyConfig: + def __init__(self, confdir=CONF_DIR, clientcerts=None, + no_upstream_cert=False, body_size_limit=None, reverse_proxy=None, + forward_proxy=None, transparent_proxy=None, authenticator=None, + ciphers=None, certs=None + ): + self.ciphers = ciphers + self.clientcerts = clientcerts + self.no_upstream_cert = no_upstream_cert + self.body_size_limit = body_size_limit + self.reverse_proxy = reverse_proxy + self.forward_proxy = forward_proxy + self.transparent_proxy = transparent_proxy + self.authenticator = authenticator + self.confdir = os.path.expanduser(confdir) + self.certstore = certutils.CertStore.from_store(self.confdir, CONF_BASENAME) + + +def process_proxy_options(parser, options): + body_size_limit = utils.parse_size(options.body_size_limit) + if options.reverse_proxy and options.transparent_proxy: + return parser.error("Can't set both reverse proxy and transparent proxy.") + + if options.transparent_proxy: + if not platform.resolver: + return parser.error("Transparent mode not supported on this platform.") + trans = dict( + resolver=platform.resolver(), + sslports=TRANSPARENT_SSL_PORTS + ) + else: + trans = None + + if options.reverse_proxy: + rp = utils.parse_proxy_spec(options.reverse_proxy) + if not rp: + return parser.error("Invalid reverse proxy specification: %s" % options.reverse_proxy) + else: + rp = None + + if options.forward_proxy: + fp = utils.parse_proxy_spec(options.forward_proxy) + if not fp: + return parser.error("Invalid forward proxy specification: %s" % options.forward_proxy) + else: + fp = None + + if options.clientcerts: + options.clientcerts = os.path.expanduser(options.clientcerts) + if not os.path.exists(options.clientcerts) or not os.path.isdir(options.clientcerts): + return parser.error( + "Client certificate directory does not exist or is not a directory: %s" % options.clientcerts + ) + + if (options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd): + if options.auth_singleuser: + if len(options.auth_singleuser.split(':')) != 2: + return parser.error("Invalid single-user specification. Please use the format username:password") + username, password = options.auth_singleuser.split(':') + password_manager = http_auth.PassManSingleUser(username, password) + elif options.auth_nonanonymous: + password_manager = http_auth.PassManNonAnon() + elif options.auth_htpasswd: + try: + password_manager = http_auth.PassManHtpasswd(options.auth_htpasswd) + except ValueError, v: + return parser.error(v.message) + authenticator = http_auth.BasicProxyAuth(password_manager, "mitmproxy") + else: + authenticator = http_auth.NullProxyAuth(None) + + certs = [] + for i in options.certs: + parts = i.split("=", 1) + if len(parts) == 1: + parts = ["*", parts[0]] + parts[1] = os.path.expanduser(parts[1]) + if not os.path.exists(parts[1]): + parser.error("Certificate file does not exist: %s"%parts[1]) + certs.append(parts) + + return ProxyConfig( + clientcerts=options.clientcerts, + body_size_limit=body_size_limit, + no_upstream_cert=options.no_upstream_cert, + reverse_proxy=rp, + forward_proxy=fp, + transparent_proxy=trans, + authenticator=authenticator, + ciphers=options.ciphers, + certs = certs, + ) + + +def ssl_option_group(parser): + group = parser.add_argument_group("SSL") + group.add_argument( + "--cert", dest='certs', default=[], type=str, + metavar = "SPEC", action="append", + help='Add an SSL certificate. SPEC is of the form "[domain=]path". '\ + 'The domain may include a wildcard, and is equal to "*" if not specified. '\ + 'The file at path is a certificate in PEM format. If a private key is included in the PEM, '\ + 'it is used, else the default key in the conf dir is used. Can be passed multiple times.' + ) + group.add_argument( + "--client-certs", action="store", + type=str, dest="clientcerts", default=None, + help="Client certificate directory." + ) + group.add_argument( + "--ciphers", action="store", + type=str, dest="ciphers", default=None, + help="SSL cipher specification." + ) \ No newline at end of file diff --git a/libmproxy/prxy/connection.py b/libmproxy/proxy/connection.py similarity index 98% rename from libmproxy/prxy/connection.py rename to libmproxy/proxy/connection.py index b1040c1ce..3a0273af3 100644 --- a/libmproxy/prxy/connection.py +++ b/libmproxy/proxy/connection.py @@ -1,9 +1,10 @@ import copy import os from .. import stateobject, utils -from .exception import ProxyError +from .primitives import ProxyError from netlib import tcp, certutils + class ClientConnection(tcp.BaseHandler, stateobject.SimpleStateObject): def __init__(self, client_connection, address, server): if client_connection: # Eventually, this object is restored from state. We don't have a connection then. diff --git a/libmproxy/proxy/primitives.py b/libmproxy/proxy/primitives.py new file mode 100644 index 000000000..8dd0e16a0 --- /dev/null +++ b/libmproxy/proxy/primitives.py @@ -0,0 +1,40 @@ +class ProxyError(Exception): + def __init__(self, code, msg, headers=None): + self.code, self.msg, self.headers = code, msg, headers + + def __str__(self): + return "ProxyError(%s, %s)" % (self.code, self.msg) + + +class ConnectionTypeChange(Exception): + """ + Gets raised if the connection type has been changed (e.g. after HTTP/1.1 101 Switching Protocols). + It's up to the raising ProtocolHandler to specify the new conntype before raising the exception. + """ + pass + + +class ProxyServerError(Exception): + pass + + +class AddressPriority(object): + """ + Enum that signifies the priority of the given address when choosing the destination host. + Higher is better (None < i) + """ + FORCE = 5 + """forward mode""" + MANUALLY_CHANGED = 4 + """user changed the target address in the ui""" + FROM_SETTINGS = 3 + """reverse proxy mode""" + FROM_CONNECTION = 2 + """derived from transparent resolver""" + FROM_PROTOCOL = 1 + """derived from protocol (e.g. absolute-form http requests)""" + + +class Log: + def __init__(self, msg): + self.msg = msg \ No newline at end of file diff --git a/libmproxy/proxy.py b/libmproxy/proxy/server.py similarity index 62% rename from libmproxy/proxy.py rename to libmproxy/proxy/server.py index ccb47c262..37ec7758b 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy/server.py @@ -1,73 +1,51 @@ -import os import socket -import threading - -from OpenSSL import SSL - -from .prxy.connection import ClientConnection, ServerConnection -from .prxy.exception import ProxyError, ConnectionTypeChange -from .prxy.server import AddressPriority -from netlib import tcp, http, certutils, http_auth -import utils -import version -import platform -import controller +from .. import version, protocol +from libmproxy.proxy.primitives import Log +from .primitives import ProxyServerError +from .connection import ClientConnection, ServerConnection +from .primitives import ProxyError, ConnectionTypeChange, AddressPriority +from netlib import tcp -TRANSPARENT_SSL_PORTS = [443, 8443] -CONF_BASENAME = "mitmproxy" -CONF_DIR = "~/.mitmproxy" -CA_CERT_NAME = "mitmproxy-ca.pem" +class DummyServer: + bound = False + + def __init__(self, config): + self.config = config + + def start_slave(self, *args): + pass + + def shutdown(self): + pass -class Log: - def __init__(self, msg): - self.msg = msg - - -class ProxyConfig: - def __init__(self, confdir=CONF_DIR, clientcerts=None, - no_upstream_cert=False, body_size_limit=None, reverse_proxy=None, - forward_proxy=None, transparent_proxy=None, authenticator=None, - ciphers=None, certs=None - ): - self.ciphers = ciphers - self.clientcerts = clientcerts - self.no_upstream_cert = no_upstream_cert - self.body_size_limit = body_size_limit - self.reverse_proxy = reverse_proxy - self.forward_proxy = forward_proxy - self.transparent_proxy = transparent_proxy - self.authenticator = authenticator - self.confdir = os.path.expanduser(confdir) - self.certstore = certutils.CertStore.from_store(self.confdir, CONF_BASENAME) - - -from . import protocol -from .protocol.http import HTTPResponse - - -class RequestReplayThread(threading.Thread): - name="RequestReplayThread" - - def __init__(self, config, flow, masterq): - self.config, self.flow, self.channel = config, flow, controller.Channel(masterq) - threading.Thread.__init__(self) - - def run(self): +class ProxyServer(tcp.TCPServer): + allow_reuse_address = True + bound = True + def __init__(self, config, port, host='', server_version=version.NAMEVERSION): + """ + Raises ProxyServerError if there's a startup problem. + """ + self.config = config + self.server_version = server_version try: - r = self.flow.request - server = ServerConnection(self.flow.server_conn.address(), None) - server.connect() - if self.flow.server_conn.ssl_established: - server.establish_ssl(self.config.clientcerts, - self.flow.server_conn.sni) - server.send(r._assemble()) - self.flow.response = HTTPResponse.from_stream(server.rfile, r.method, body_size_limit=self.config.body_size_limit) - self.channel.ask("response", self.flow.response) - except (ProxyError, http.HttpError, tcp.NetLibError), v: - self.flow.error = protocol.primitives.Error(str(v)) - self.channel.ask("error", self.flow.error) + tcp.TCPServer.__init__(self, (host, port)) + except socket.error, v: + raise ProxyServerError('Error starting proxy server: ' + v.strerror) + self.channel = None + + def start_slave(self, klass, channel): + slave = klass(channel, self) + slave.start() + + def set_channel(self, channel): + self.channel = channel + + def handle_client_connection(self, conn, client_address): + h = ConnectionHandler(self.config, conn, client_address, self, self.channel, self.server_version) + h.handle() + h.finish() class ConnectionHandler: @@ -174,7 +152,7 @@ class ConnectionHandler: """ Sets a new server address with the given priority. Does not re-establish either connection or SSL handshake. - @type priority: libmproxy.prxy.server.AddressPriority + @type priority: libmproxy.proxy.primitives.AddressPriority """ address = tcp.Address.wrap(address) @@ -241,7 +219,7 @@ class ConnectionHandler: raise ProxyError(502, "SSL to Client already established.") cert, key = self.find_cert() self.client_conn.convert_to_ssl( - cert, key, + cert, key, handle_sni = self.handle_sni, cipher_list = self.config.ciphers ) @@ -306,148 +284,4 @@ class ConnectionHandler: # An unhandled exception in this method will core dump PyOpenSSL, so # make dang sure it doesn't happen. except Exception, e: # pragma: no cover - pass - - -class ProxyServerError(Exception): - pass - - -class ProxyServer(tcp.TCPServer): - allow_reuse_address = True - bound = True - def __init__(self, config, port, host='', server_version=version.NAMEVERSION): - """ - Raises ProxyServerError if there's a startup problem. - """ - self.config = config - self.server_version = server_version - try: - tcp.TCPServer.__init__(self, (host, port)) - except socket.error, v: - raise ProxyServerError('Error starting proxy server: ' + v.strerror) - self.channel = None - - def start_slave(self, klass, channel): - slave = klass(channel, self) - slave.start() - - def set_channel(self, channel): - self.channel = channel - - def handle_client_connection(self, conn, client_address): - h = ConnectionHandler(self.config, conn, client_address, self, self.channel, self.server_version) - h.handle() - h.finish() - - -class DummyServer: - bound = False - - def __init__(self, config): - self.config = config - - def start_slave(self, *args): - pass - - def shutdown(self): - pass - - -# Command-line utils -def ssl_option_group(parser): - group = parser.add_argument_group("SSL") - group.add_argument( - "--cert", dest='certs', default=[], type=str, - metavar = "SPEC", action="append", - help='Add an SSL certificate. SPEC is of the form "[domain=]path". '\ - 'The domain may include a wildcard, and is equal to "*" if not specified. '\ - 'The file at path is a certificate in PEM format. If a private key is included in the PEM, '\ - 'it is used, else the default key in the conf dir is used. Can be passed multiple times.' - ) - group.add_argument( - "--client-certs", action="store", - type=str, dest="clientcerts", default=None, - help="Client certificate directory." - ) - group.add_argument( - "--ciphers", action="store", - type=str, dest="ciphers", default=None, - help="SSL cipher specification." - ) - - -def process_proxy_options(parser, options): - body_size_limit = utils.parse_size(options.body_size_limit) - if options.reverse_proxy and options.transparent_proxy: - return parser.error("Can't set both reverse proxy and transparent proxy.") - - if options.transparent_proxy: - if not platform.resolver: - return parser.error("Transparent mode not supported on this platform.") - trans = dict( - resolver=platform.resolver(), - sslports=TRANSPARENT_SSL_PORTS - ) - else: - trans = None - - if options.reverse_proxy: - rp = utils.parse_proxy_spec(options.reverse_proxy) - if not rp: - return parser.error("Invalid reverse proxy specification: %s" % options.reverse_proxy) - else: - rp = None - - if options.forward_proxy: - fp = utils.parse_proxy_spec(options.forward_proxy) - if not fp: - return parser.error("Invalid forward proxy specification: %s" % options.forward_proxy) - else: - fp = None - - if options.clientcerts: - options.clientcerts = os.path.expanduser(options.clientcerts) - if not os.path.exists(options.clientcerts) or not os.path.isdir(options.clientcerts): - return parser.error( - "Client certificate directory does not exist or is not a directory: %s" % options.clientcerts - ) - - if (options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd): - if options.auth_singleuser: - if len(options.auth_singleuser.split(':')) != 2: - return parser.error("Invalid single-user specification. Please use the format username:password") - username, password = options.auth_singleuser.split(':') - password_manager = http_auth.PassManSingleUser(username, password) - elif options.auth_nonanonymous: - password_manager = http_auth.PassManNonAnon() - elif options.auth_htpasswd: - try: - password_manager = http_auth.PassManHtpasswd(options.auth_htpasswd) - except ValueError, v: - return parser.error(v.message) - authenticator = http_auth.BasicProxyAuth(password_manager, "mitmproxy") - else: - authenticator = http_auth.NullProxyAuth(None) - - certs = [] - for i in options.certs: - parts = i.split("=", 1) - if len(parts) == 1: - parts = ["*", parts[0]] - parts[1] = os.path.expanduser(parts[1]) - if not os.path.exists(parts[1]): - parser.error("Certificate file does not exist: %s"%parts[1]) - certs.append(parts) - - return ProxyConfig( - clientcerts=options.clientcerts, - body_size_limit=body_size_limit, - no_upstream_cert=options.no_upstream_cert, - reverse_proxy=rp, - forward_proxy=fp, - transparent_proxy=trans, - authenticator=authenticator, - ciphers=options.ciphers, - certs = certs, - ) + pass \ No newline at end of file diff --git a/libmproxy/prxy/exception.py b/libmproxy/prxy/exception.py deleted file mode 100644 index c43a5d75d..000000000 --- a/libmproxy/prxy/exception.py +++ /dev/null @@ -1,14 +0,0 @@ -class ProxyError(Exception): - def __init__(self, code, msg, headers=None): - self.code, self.msg, self.headers = code, msg, headers - - def __str__(self): - return "ProxyError(%s, %s)" % (self.code, self.msg) - - -class ConnectionTypeChange(Exception): - """ - Gets raised if the connection type has been changed (e.g. after HTTP/1.1 101 Switching Protocols). - It's up to the raising ProtocolHandler to specify the new conntype before raising the exception. - """ - pass \ No newline at end of file diff --git a/libmproxy/prxy/server.py b/libmproxy/prxy/server.py deleted file mode 100644 index 441b29b47..000000000 --- a/libmproxy/prxy/server.py +++ /dev/null @@ -1,18 +0,0 @@ -__author__ = 'user' - - -class AddressPriority(object): - """ - Enum that signifies the priority of the given address when choosing the destination host. - Higher is better (None < i) - """ - FORCE = 5 - """forward mode""" - MANUALLY_CHANGED = 4 - """user changed the target address in the ui""" - FROM_SETTINGS = 3 - """reverse proxy mode""" - FROM_CONNECTION = 2 - """derived from transparent resolver""" - FROM_PROTOCOL = 1 - """derived from protocol (e.g. absolute-form http requests)""" \ No newline at end of file diff --git a/mitmdump b/mitmdump index 49d129d6a..5ab7c0766 100755 --- a/mitmdump +++ b/mitmdump @@ -1,6 +1,9 @@ #!/usr/bin/env python import sys, signal from libmproxy import proxy, dump, cmdline +from libmproxy.proxy.config import process_proxy_options +from libmproxy.proxy.primitives import ProxyServerError +from libmproxy.proxy.server import DummyServer, ProxyServer import libmproxy.version, netlib.version import argparse @@ -25,13 +28,13 @@ if __name__ == '__main__': if options.quiet: options.verbose = 0 - proxyconfig = proxy.process_proxy_options(parser, options) + proxyconfig = process_proxy_options(parser, options) if options.no_server: - server = proxy.DummyServer(proxyconfig) + server = DummyServer(proxyconfig) else: try: - server = proxy.ProxyServer(proxyconfig, options.port, options.addr) - except proxy.ProxyServerError, v: + server = ProxyServer(proxyconfig, options.port, options.addr) + except ProxyServerError, v: print >> sys.stderr, "mitmdump:", v.args[0] sys.exit(1) diff --git a/mitmproxy b/mitmproxy index 7cc9e3f94..934d17725 100755 --- a/mitmproxy +++ b/mitmproxy @@ -1,6 +1,9 @@ #!/usr/bin/env python import sys, argparse, os from libmproxy import proxy, console, cmdline +from libmproxy.proxy.config import process_proxy_options +from libmproxy.proxy.primitives import ProxyServerError +from libmproxy.proxy.server import DummyServer, ProxyServer import libmproxy.version, netlib.version from libmproxy.console import palettes @@ -33,14 +36,14 @@ if __name__ == '__main__': ) options = parser.parse_args() - config = proxy.process_proxy_options(parser, options) + config = process_proxy_options(parser, options) if options.no_server: - server = proxy.DummyServer(config) + server = DummyServer(config) else: try: - server = proxy.ProxyServer(config, options.port, options.addr) - except proxy.ProxyServerError, v: + server = ProxyServer(config, options.port, options.addr) + except ProxyServerError, v: print >> sys.stderr, "mitmproxy:", v.args[0] sys.exit(1) diff --git a/test/test_dump.py b/test/test_dump.py index c5c231fa4..0f7d9bea0 100644 --- a/test/test_dump.py +++ b/test/test_dump.py @@ -1,6 +1,7 @@ import os from cStringIO import StringIO -from libmproxy import dump, flow, proxy, prxy +from libmproxy import dump, flow, proxy +from libmproxy.proxy.primitives import Log import tutils import mock @@ -21,13 +22,13 @@ def test_strfuncs(): class TestDumpMaster: def _cycle(self, m, content): req = tutils.treq(content=content) - l = proxy.Log("connect") + l = Log("connect") l.reply = mock.MagicMock() m.handle_log(l) cc = req.flow.client_conn cc.reply = mock.MagicMock() m.handle_clientconnect(cc) - sc = prxy.connection.ServerConnection((req.get_host(), req.get_port()), None) + sc = proxy.connection.ServerConnection((req.get_host(), req.get_port()), None) sc.reply = mock.MagicMock() m.handle_serverconnection(sc) m.handle_request(req) diff --git a/test/test_flow.py b/test/test_flow.py index c7e39f738..2365c08c9 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -1,10 +1,10 @@ import Queue, time, os.path from cStringIO import StringIO import email.utils -from libmproxy import filt, protocol, controller, utils, tnetstring, proxy, flow +from libmproxy import filt, protocol, controller, utils, tnetstring, flow from libmproxy.protocol.primitives import Error, Flow -from libmproxy.protocol.http import decoded -from libmproxy.prxy.connection import ClientConnection, ServerConnection +from libmproxy.protocol.http import decoded, CONTENT_MISSING +from libmproxy.proxy.connection import ClientConnection, ServerConnection from netlib import tcp import tutils @@ -566,7 +566,7 @@ class TestFlowMaster: s = flow.State() fm = flow.FlowMaster(None, s) f = tutils.tflow_full() - f.request.content = flow.CONTENT_MISSING + f.request.content = CONTENT_MISSING assert "missing" in fm.replay_request(f) f.intercepting = True @@ -796,7 +796,7 @@ class TestRequest: assert r._assemble() assert r.size() == len(r._assemble()) - r.content = flow.CONTENT_MISSING + r.content = CONTENT_MISSING tutils.raises("Cannot assemble flow with CONTENT_MISSING", r._assemble) def test_get_url(self): @@ -1004,7 +1004,7 @@ class TestResponse: assert resp._assemble() assert resp.size() == len(resp._assemble()) - resp.content = flow.CONTENT_MISSING + resp.content = CONTENT_MISSING tutils.raises("Cannot assemble flow with CONTENT_MISSING", resp._assemble) def test_refresh(self): diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index 3f37928cb..6ff0cb65a 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -1,4 +1,3 @@ -from libmproxy import proxy # FIXME: Remove from libmproxy.protocol.http import * from libmproxy.protocol import KILL from cStringIO import StringIO diff --git a/test/test_proxy.py b/test/test_proxy.py index 2a4a250e6..f53aa7621 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -1,7 +1,9 @@ import argparse -from libmproxy import proxy, flow, cmdline -from libmproxy.prxy.connection import ServerConnection -from libmproxy.prxy.exception import ProxyError +from libmproxy import cmdline +from libmproxy.proxy.config import process_proxy_options +from libmproxy.proxy.connection import ServerConnection +from libmproxy.proxy.primitives import ProxyError +from libmproxy.proxy.server import DummyServer, ProxyServer import tutils from libpathod import test from netlib import http, tcp @@ -58,7 +60,7 @@ class TestProcessProxyOptions: cmdline.common_options(parser) opts = parser.parse_args(args=args) m = MockParser() - return m, proxy.process_proxy_options(m, opts) + return m, process_proxy_options(m, opts) def assert_err(self, err, *args): m, p = self.p(*args) @@ -117,12 +119,12 @@ class TestProxyServer: parser = argparse.ArgumentParser() cmdline.common_options(parser) opts = parser.parse_args(args=[]) - tutils.raises("error starting proxy server", proxy.ProxyServer, opts, 1) + tutils.raises("error starting proxy server", ProxyServer, opts, 1) class TestDummyServer: def test_simple(self): - d = proxy.DummyServer(None) + d = DummyServer(None) d.start_slave() d.shutdown() diff --git a/test/test_server.py b/test/test_server.py index ed21e75ce..43ef546d1 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -3,8 +3,8 @@ import mock from netlib import tcp, http_auth, http from libpathod import pathoc, pathod import tutils, tservers -from libmproxy import flow, proxy from libmproxy.protocol import KILL +from libmproxy.protocol.http import CONTENT_MISSING """ Note that the choice of response code in these tests matters more than you @@ -381,7 +381,7 @@ class TestTransparentResolveError(tservers.TransparentProxTest): class MasterIncomplete(tservers.TestMaster): def handle_request(self, m): resp = tutils.tresp() - resp.content = flow.CONTENT_MISSING + resp.content = CONTENT_MISSING m.reply(resp) diff --git a/test/tservers.py b/test/tservers.py index cf9b3f73e..bfafc8cd6 100644 --- a/test/tservers.py +++ b/test/tservers.py @@ -2,8 +2,10 @@ import os.path import threading, Queue import shutil, tempfile import flask +from libmproxy.proxy.config import ProxyConfig +from libmproxy.proxy.server import ProxyServer import libpathod.test, libpathod.pathoc -from libmproxy import proxy, flow, controller +from libmproxy import flow, controller from libmproxy.cmdline import APP_HOST, APP_PORT import tutils @@ -24,7 +26,7 @@ def errapp(environ, start_response): class TestMaster(flow.FlowMaster): def __init__(self, config): - s = proxy.ProxyServer(config, 0) + s = ProxyServer(config, 0) state = flow.State() flow.FlowMaster.__init__(self, s, state) self.apps.add(testapp, "testapp", 80) @@ -84,7 +86,7 @@ class ProxTestBase(object): cls.server2 = libpathod.test.Daemon(ssl=cls.ssl, ssloptions=cls.ssloptions) pconf = cls.get_proxy_config() cls.confdir = os.path.join(tempfile.gettempdir(), "mitmproxy") - config = proxy.ProxyConfig( + config = ProxyConfig( no_upstream_cert = cls.no_upstream_cert, confdir = cls.confdir, authenticator = cls.authenticator, @@ -256,7 +258,7 @@ class ChainProxTest(ProxTestBase): Chain n instances of mitmproxy in a row - because we can. """ n = 2 - chain_config = [lambda: proxy.ProxyConfig( + chain_config = [lambda: ProxyConfig( )] * n @classmethod def setupAll(cls): diff --git a/test/tutils.py b/test/tutils.py index 8690d67d0..3f6592b0e 100644 --- a/test/tutils.py +++ b/test/tutils.py @@ -1,8 +1,8 @@ import os, shutil, tempfile from contextlib import contextmanager -from libmproxy import flow, utils, controller, proxy +from libmproxy import flow, utils, controller from libmproxy.protocol import http -from libmproxy.prxy.connection import ClientConnection, ServerConnection +from libmproxy.proxy.connection import ClientConnection, ServerConnection import mock_urwid from libmproxy.console.flowview import FlowView from libmproxy.console import ConsoleState