mirror of
https://github.com/zhigang1992/mitmproxy.git
synced 2026-05-04 20:10:50 +08:00
remove proxy mode abstraction: always be clear which mode we are in
This commit is contained in:
@@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
from netlib import http_auth, certutils
|
||||
from .. import utils, platform
|
||||
from .primitives import ConstUpstreamServerResolver, TransparentUpstreamServerResolver
|
||||
from .primitives import RegularProxyMode, TransparentProxyMode, UpstreamProxyMode, ReverseProxyMode
|
||||
|
||||
TRANSPARENT_SSL_PORTS = [443, 8443]
|
||||
CONF_BASENAME = "mitmproxy"
|
||||
@@ -26,25 +26,17 @@ class ProxyConfig:
|
||||
self.body_size_limit = body_size_limit
|
||||
|
||||
if mode == "transparent":
|
||||
get_upstream_server = TransparentUpstreamServerResolver(platform.resolver(), TRANSPARENT_SSL_PORTS)
|
||||
http_form_in_default, http_form_out_default = "relative", "relative"
|
||||
self.mode = TransparentProxyMode(platform.resolver(), TRANSPARENT_SSL_PORTS)
|
||||
elif mode == "reverse":
|
||||
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||
http_form_in_default, http_form_out_default = "relative", "relative"
|
||||
self.mode = ReverseProxyMode(upstream_server)
|
||||
elif mode == "upstream":
|
||||
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||
http_form_in_default, http_form_out_default = "absolute", "absolute"
|
||||
elif upstream_server:
|
||||
get_upstream_server = ConstUpstreamServerResolver(upstream_server)
|
||||
http_form_in_default, http_form_out_default = "absolute", "relative"
|
||||
self.mode = UpstreamProxyMode(upstream_server)
|
||||
else:
|
||||
get_upstream_server, http_form_in_default, http_form_out_default = None, "absolute", "relative"
|
||||
http_form_in = http_form_in or http_form_in_default
|
||||
http_form_out = http_form_out or http_form_out_default
|
||||
self.mode = RegularProxyMode()
|
||||
|
||||
self.mode.http_form_in = http_form_in or self.mode.http_form_in
|
||||
self.mode.http_form_out = http_form_out or self.mode.http_form_out
|
||||
|
||||
self.get_upstream_server = get_upstream_server
|
||||
self.http_form_in = http_form_in
|
||||
self.http_form_out = http_form_out
|
||||
self.ignore = parse_host_pattern(ignore)
|
||||
self.authenticator = authenticator
|
||||
self.confdir = os.path.expanduser(confdir)
|
||||
@@ -74,13 +66,9 @@ def process_proxy_options(parser, options):
|
||||
c += 1
|
||||
mode = "upstream"
|
||||
upstream_server = options.upstream_proxy
|
||||
if options.manual_destination_server:
|
||||
c += 1
|
||||
mode = "manual"
|
||||
upstream_server = options.manual_destination_server
|
||||
if c > 1:
|
||||
return parser.error("Transparent mode, reverse mode, upstream proxy mode and "
|
||||
"specification of an upstream server are mutually exclusive.")
|
||||
return parser.error("Transparent mode, reverse mode and upstream proxy mode "
|
||||
"are mutually exclusive.")
|
||||
|
||||
if options.clientcerts:
|
||||
options.clientcerts = os.path.expanduser(options.clientcerts)
|
||||
|
||||
@@ -11,28 +11,54 @@ class ProxyServerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class UpstreamServerResolver(object):
|
||||
def __call__(self, conn):
|
||||
class ProxyMode(object):
|
||||
http_form_in = None
|
||||
http_form_out = None
|
||||
|
||||
def get_upstream_server(self, conn):
|
||||
"""
|
||||
Returns the address of the server to connect to.
|
||||
Returns None if the address needs to be determined on the protocol level (regular proxy mode)
|
||||
"""
|
||||
raise NotImplementedError # pragma: nocover
|
||||
raise NotImplementedError() # pragma: nocover
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.__class__.__name__.replace("ProxyMode", "").lower()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
Allow comparisions with "regular" etc.
|
||||
"""
|
||||
if isinstance(other, ProxyMode):
|
||||
return self is other
|
||||
else:
|
||||
return self.name == other
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
|
||||
class ConstUpstreamServerResolver(UpstreamServerResolver):
|
||||
def __init__(self, dst):
|
||||
self.dst = dst
|
||||
class RegularProxyMode(ProxyMode):
|
||||
http_form_in = "absolute"
|
||||
http_form_out = "relative"
|
||||
|
||||
def __call__(self, conn):
|
||||
return self.dst
|
||||
def get_upstream_server(self, conn):
|
||||
return None
|
||||
|
||||
|
||||
class TransparentUpstreamServerResolver(UpstreamServerResolver):
|
||||
class TransparentProxyMode(ProxyMode):
|
||||
http_form_in = "relative"
|
||||
http_form_out = "relative"
|
||||
|
||||
def __init__(self, resolver, sslports):
|
||||
self.resolver = resolver
|
||||
self.sslports = sslports
|
||||
|
||||
def __call__(self, conn):
|
||||
def get_upstream_server(self, conn):
|
||||
try:
|
||||
dst = self.resolver.original_addr(conn)
|
||||
except Exception, e:
|
||||
@@ -45,6 +71,24 @@ class TransparentUpstreamServerResolver(UpstreamServerResolver):
|
||||
return [ssl, ssl] + list(dst)
|
||||
|
||||
|
||||
class _ConstDestinationProxyMode(ProxyMode):
|
||||
def __init__(self, dst):
|
||||
self.dst = dst
|
||||
|
||||
def get_upstream_server(self, conn):
|
||||
return self.dst
|
||||
|
||||
|
||||
class ReverseProxyMode(_ConstDestinationProxyMode):
|
||||
http_form_in = "relative"
|
||||
http_form_out = "relative"
|
||||
|
||||
|
||||
class UpstreamProxyMode(_ConstDestinationProxyMode):
|
||||
http_form_in = "absolute"
|
||||
http_form_out = "absolute"
|
||||
|
||||
|
||||
class Log:
|
||||
def __init__(self, msg, level="info"):
|
||||
self.msg = msg
|
||||
|
||||
@@ -73,14 +73,16 @@ class ConnectionHandler:
|
||||
|
||||
# Can we already identify the target server and connect to it?
|
||||
client_ssl, server_ssl = False, False
|
||||
if self.config.get_upstream_server:
|
||||
upstream_info = self.config.get_upstream_server(self.client_conn.connection)
|
||||
upstream_info = self.config.mode.get_upstream_server(self.client_conn.connection)
|
||||
if upstream_info:
|
||||
self.set_server_address(upstream_info[2:])
|
||||
client_ssl, server_ssl = upstream_info[:2]
|
||||
if self.check_ignore_address(self.server_conn.address):
|
||||
self.log("Ignore host: %s:%s" % self.server_conn.address(), "info")
|
||||
self.conntype = "tcp"
|
||||
client_ssl, server_ssl = False, False
|
||||
else:
|
||||
pass # No upstream info from the metadata: upstream info in the protocol (e.g. HTTP absolute-form)
|
||||
|
||||
self.channel.ask("clientconnect", self)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user