This commit is contained in:
Maximilian Hils 2014-07-26 12:02:18 +02:00
parent a73ad1d945
commit e9c834a30d
6 changed files with 16 additions and 12 deletions

View File

@ -672,12 +672,7 @@ class FlowMaster(controller.Master):
self.run_script_hook("clientdisconnect", r)
r.reply()
def handle_serverconnection(self, sc):
# To unify the mitmproxy script API, we call the script hook
# "serverconnect" rather than "serverconnection". As things are handled
# differently in libmproxy (ClientConnect + ClientDisconnect vs
# ServerConnection class), there is no "serverdisonnect" event at the
# moment.
def handle_serverconnect(self, sc):
self.run_script_hook("serverconnect", sc)
sc.reply()
@ -791,7 +786,7 @@ class FilteredFlowWriter:
class RequestReplayThread(threading.Thread):
name="RequestReplayThread"
name = "RequestReplayThread"
def __init__(self, config, flow, masterq, should_exit):
self.config, self.flow, self.channel = config, flow, controller.Channel(masterq, should_exit)

View File

@ -1035,12 +1035,14 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin):
if not self.c.config.get_upstream_server:
self.c.set_server_address((request.host, request.port),
proxy.AddressPriority.FROM_PROTOCOL)
self.c.establish_server_connection()
flow.server_conn = self.c.server_conn # Update server_conn attribute on the flow
self.c.client_conn.send(
'HTTP/1.1 200 Connection established\r\n' +
('Proxy-agent: %s\r\n' % self.c.server_version) +
'\r\n'
)
self.ssl_upgrade()
self.skip_authentication = True
return False

View File

@ -181,6 +181,7 @@ class TemporaryServerChangeMixin(object):
self.c.del_server_connection()
self.c.set_server_address(address, priority)
self.c.establish_server_connection(ask=False)
if ssl:
self.c.establish_ssl(server=True)

View File

@ -146,15 +146,20 @@ class ConnectionHandler:
self.log("Set new server address: %s:%s" % (address.host, address.port), "debug")
self.server_conn = ServerConnection(address, priority)
def establish_server_connection(self):
def establish_server_connection(self, ask=True):
"""
Establishes a new server connection.
If there is already an existing server connection, the function returns immediately.
By default, this function ".ask"s the proxy master. This is deadly if this function is already called from the
master (e.g. via change_server), because this navigates us in a simple deadlock (the master is single-threaded).
In these scenarios, ask=False can be passed to suppress the call to the master.
"""
if self.server_conn.connection:
return
self.log("serverconnect", "debug", ["%s:%s" % self.server_conn.address()[:2]])
self.channel.tell("serverconnect", self)
if ask:
self.channel.ask("serverconnect", self)
try:
self.server_conn.connect()
except tcp.NetLibError, v:
@ -185,9 +190,10 @@ class ConnectionHandler:
self.log("Establish SSL", "debug", subs)
if server:
if not self.server_conn or not self.server_conn.connection:
raise ProxyError(502, "No server connection.")
if self.server_conn.ssl_established:
raise ProxyError(502, "SSL to Server already established.")
self.establish_server_connection() # make sure there is a server connection.
self.server_conn.establish_ssl(self.config.clientcerts, self.sni)
if client:
if self.client_conn.ssl_established:

View File

@ -30,7 +30,7 @@ class TestDumpMaster:
m.handle_clientconnect(cc)
sc = proxy.connection.ServerConnection((req.get_host(), req.get_port()), None)
sc.reply = mock.MagicMock()
m.handle_serverconnection(sc)
m.handle_serverconnect(sc)
m.handle_request(req)
resp = tutils.tresp(req, content=content)
f = m.handle_response(resp)

View File

@ -589,7 +589,7 @@ class TestFlowMaster:
assert fm.scripts[0].ns["log"][-1] == "clientconnect"
sc = ServerConnection((req.get_host(), req.get_port()), None)
sc.reply = controller.DummyReply()
fm.handle_serverconnection(sc)
fm.handle_serverconnect(sc)
assert fm.scripts[0].ns["log"][-1] == "serverconnect"
f = fm.handle_request(req)
assert fm.scripts[0].ns["log"][-1] == "request"