aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/flow.py9
-rw-r--r--libmproxy/protocol/http.py2
-rw-r--r--libmproxy/protocol/primitives.py1
-rw-r--r--libmproxy/proxy/server.py12
4 files changed, 14 insertions, 10 deletions
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index b6b49022..5062c202 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -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)
diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py
index 8a321078..8f9d5f5d 100644
--- a/libmproxy/protocol/http.py
+++ b/libmproxy/protocol/http.py
@@ -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
diff --git a/libmproxy/protocol/primitives.py b/libmproxy/protocol/primitives.py
index 8c0ea5db..5743bb6a 100644
--- a/libmproxy/protocol/primitives.py
+++ b/libmproxy/protocol/primitives.py
@@ -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)
diff --git a/libmproxy/proxy/server.py b/libmproxy/proxy/server.py
index 72228f16..61369775 100644
--- a/libmproxy/proxy/server.py
+++ b/libmproxy/proxy/server.py
@@ -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: