From 2aa175a6ca657db0b4faa2aeb84a78b7ef3c4761 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 29 Jan 2013 10:55:19 +1300 Subject: Stub implementation of a server connection pool. --- libmproxy/proxy.py | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index f14e4e3e..3bbb82ba 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -107,12 +107,30 @@ class ServerConnection(tcp.TCPClient): except IOError: pass +class ServerConnectionPool: + def __init__(self, config): + self.config = config + self.conn = None + + def get_connection(self, scheme, host, port): + sc = self.conn + if self.conn and (host, port) != (sc.host, sc.port): + sc.terminate() + self.conn = None + if not self.conn: + try: + self.conn = ServerConnection(self.config, host, port) + self.conn.connect(scheme) + except tcp.NetLibError, v: + raise ProxyError(502, v) + return self.conn + class ProxyHandler(tcp.BaseHandler): def __init__(self, config, connection, client_address, server, mqueue, server_version): self.mqueue, self.server_version = mqueue, server_version self.config = config - self.server_conn = None + self.server_conn_pool = ServerConnectionPool(config) self.proxy_connect_state = None self.sni = None tcp.BaseHandler.__init__(self, connection, client_address, server) @@ -133,18 +151,6 @@ class ProxyHandler(tcp.BaseHandler): ) cd._send(self.mqueue) - def server_connect(self, scheme, host, port): - sc = self.server_conn - if sc and (host, port) != (sc.host, sc.port): - sc.terminate() - self.server_conn = None - if not self.server_conn: - try: - self.server_conn = ServerConnection(self.config, host, port) - self.server_conn.connect(scheme) - except tcp.NetLibError, v: - raise ProxyError(502, v) - def handle_request(self, cc): try: request, err = None, None @@ -173,21 +179,21 @@ class ProxyHandler(tcp.BaseHandler): scheme, host, port = self.config.reverse_proxy else: scheme, host, port = request.scheme, request.host, request.port - self.server_connect(scheme, host, port) - self.server_conn.send(request) - self.server_conn.rfile.reset_timestamps() + sc = self.server_conn_pool.get_connection(scheme, host, port) + sc.send(request) + sc.rfile.reset_timestamps() httpversion, code, msg, headers, content = http.read_response( - self.server_conn.rfile, + sc.rfile, request.method, self.config.body_size_limit ) response = flow.Response( - request, httpversion, code, msg, headers, content, self.server_conn.cert, self.server_conn.rfile.first_byte_timestamp, utils.timestamp() + request, httpversion, code, msg, headers, content, sc.cert, + sc.rfile.first_byte_timestamp, utils.timestamp() ) - response = response._send(self.mqueue) if response is None: - self.server_conn.terminate() + sc.terminate() if response is None: return self.send_response(response) @@ -310,7 +316,7 @@ class ProxyHandler(tcp.BaseHandler): self.rfile.first_byte_timestamp, utils.timestamp() ) - + def read_request_proxy(self, client_conn): line = self.get_line(self.rfile) if line == "": -- cgit v1.2.3 From 782bbee8c0a7d14be25e87d61c9c6db03b532eb7 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 29 Jan 2013 11:35:57 +1300 Subject: Unit tests for ServerConnectionPool --- libmproxy/proxy.py | 1 + 1 file changed, 1 insertion(+) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 3bbb82ba..f2c6db1f 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -107,6 +107,7 @@ class ServerConnection(tcp.TCPClient): except IOError: pass + class ServerConnectionPool: def __init__(self, config): self.config = config -- cgit v1.2.3 From aaf892e3afc682b2dc2a166a96872420e50092cd Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 17 Feb 2013 12:42:48 +1300 Subject: Significantly refactor the master/slave message passing interface. --- libmproxy/proxy.py | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index f2c6db1f..1fbb6d58 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -29,9 +29,8 @@ class ProxyError(Exception): return "ProxyError(%s, %s)"%(self.code, self.msg) -class Log(controller.Msg): +class Log: def __init__(self, msg): - controller.Msg.__init__(self) self.msg = msg @@ -51,7 +50,7 @@ class ProxyConfig: class RequestReplayThread(threading.Thread): def __init__(self, config, flow, masterq): - self.config, self.flow, self.masterq = config, flow, masterq + self.config, self.flow, self.channel = config, flow, controller.Channel(masterq) threading.Thread.__init__(self) def run(self): @@ -66,10 +65,10 @@ class RequestReplayThread(threading.Thread): response = flow.Response( self.flow.request, httpversion, code, msg, headers, content, server.cert ) - response._send(self.masterq) + self.channel.ask(response) except (ProxyError, http.HttpError, tcp.NetLibError), v: err = flow.Error(self.flow.request, str(v)) - err._send(self.masterq) + self.channel.ask(err) class ServerConnection(tcp.TCPClient): @@ -128,8 +127,8 @@ class ServerConnectionPool: class ProxyHandler(tcp.BaseHandler): - def __init__(self, config, connection, client_address, server, mqueue, server_version): - self.mqueue, self.server_version = mqueue, server_version + def __init__(self, config, connection, client_address, server, channel, server_version): + self.channel, self.server_version = channel, server_version self.config = config self.server_conn_pool = ServerConnectionPool(config) self.proxy_connect_state = None @@ -139,18 +138,18 @@ class ProxyHandler(tcp.BaseHandler): def handle(self): cc = flow.ClientConnect(self.client_address) self.log(cc, "connect") - cc._send(self.mqueue) + self.channel.ask(cc) while self.handle_request(cc) and not cc.close: pass cc.close = True - cd = flow.ClientDisconnect(cc) + cd = flow.ClientDisconnect(cc) self.log( cc, "disconnect", [ "handled %s requests"%cc.requestcount] ) - cd._send(self.mqueue) + self.channel.ask(cd) def handle_request(self, cc): try: @@ -167,14 +166,14 @@ class ProxyHandler(tcp.BaseHandler): self.log(cc, "Error in wsgi app.", err.split("\n")) return else: - request = request._send(self.mqueue) + request = self.channel.ask(request) if request is None: return if isinstance(request, flow.Response): response = request request = False - response = response._send(self.mqueue) + response = self.channel.ask(response) else: if self.config.reverse_proxy: scheme, host, port = self.config.reverse_proxy @@ -192,7 +191,7 @@ class ProxyHandler(tcp.BaseHandler): request, httpversion, code, msg, headers, content, sc.cert, sc.rfile.first_byte_timestamp, utils.timestamp() ) - response = response._send(self.mqueue) + response = self.channel.ask(response) if response is None: sc.terminate() if response is None: @@ -214,7 +213,7 @@ class ProxyHandler(tcp.BaseHandler): if request: err = flow.Error(request, cc.error) - err._send(self.mqueue) + self.channel.ask(err) self.log( cc, cc.error, ["url: %s"%request.get_url()] @@ -235,7 +234,7 @@ class ProxyHandler(tcp.BaseHandler): msg.append(" -> "+i) msg = "\n".join(msg) l = Log(msg) - l._send(self.mqueue) + self.channel.ask(l) def find_cert(self, host, port, sni): if self.config.certfile: @@ -438,18 +437,18 @@ class ProxyServer(tcp.TCPServer): tcp.TCPServer.__init__(self, (address, port)) except socket.error, v: raise ProxyServerError('Error starting proxy server: ' + v.strerror) - self.masterq = None + self.channel = None self.apps = AppRegistry() - def start_slave(self, klass, masterq): - slave = klass(masterq, self) + def start_slave(self, klass, channel): + slave = klass(channel, self) slave.start() - def set_mqueue(self, q): - self.masterq = q + def set_channel(self, channel): + self.channel = channel def handle_connection(self, request, client_address): - h = ProxyHandler(self.config, request, client_address, self, self.masterq, self.server_version) + h = ProxyHandler(self.config, request, client_address, self, self.channel, self.server_version) h.handle() try: h.finish() @@ -487,7 +486,7 @@ class DummyServer: def __init__(self, config): self.config = config - def start_slave(self, klass, masterq): + def start_slave(self, klass, channel): pass def shutdown(self): -- cgit v1.2.3 From 7800b7c9103ae119a13b81048a84f626850cf04f Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 23 Feb 2013 14:08:28 +1300 Subject: Refactor proxy core communications to be clearer. --- libmproxy/proxy.py | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 1fbb6d58..6d476c7b 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -20,6 +20,8 @@ from netlib import odict, tcp, http, wsgi, certutils, http_status import utils, flow, version, platform, controller import authentication +KILL = 0 + class ProxyError(Exception): def __init__(self, code, msg, headers=None): @@ -149,7 +151,7 @@ class ProxyHandler(tcp.BaseHandler): [ "handled %s requests"%cc.requestcount] ) - self.channel.ask(cd) + self.channel.tell(cd) def handle_request(self, cc): try: @@ -166,15 +168,15 @@ class ProxyHandler(tcp.BaseHandler): self.log(cc, "Error in wsgi app.", err.split("\n")) return else: - request = self.channel.ask(request) - if request is None: + request_reply = self.channel.ask(request) + if request_reply == KILL: return - - if isinstance(request, flow.Response): - response = request + elif isinstance(request_reply, flow.Response): request = False - response = self.channel.ask(response) + response = request_reply + response_reply = self.channel.ask(response) else: + request = request_reply if self.config.reverse_proxy: scheme, host, port = self.config.reverse_proxy else: @@ -191,20 +193,24 @@ class ProxyHandler(tcp.BaseHandler): request, httpversion, code, msg, headers, content, sc.cert, sc.rfile.first_byte_timestamp, utils.timestamp() ) - response = self.channel.ask(response) - if response is None: + response_reply = self.channel.ask(response) + # Not replying to the server invalidates the server connection, so we terminate. + if response_reply == KILL: sc.terminate() - if response is None: - return - self.send_response(response) - if request and http.request_connection_close(request.httpversion, request.headers): - return - # We could keep the client connection when the server - # connection needs to go away. However, we want to mimic - # behaviour as closely as possible to the client, so we - # disconnect. - if http.response_connection_close(response.httpversion, response.headers): + + if response_reply == KILL: return + else: + response = response_reply + self.send_response(response) + if request and http.request_connection_close(request.httpversion, request.headers): + return + # We could keep the client connection when the server + # connection needs to go away. However, we want to mimic + # behaviour as closely as possible to the client, so we + # disconnect. + if http.response_connection_close(response.httpversion, response.headers): + return except (IOError, ProxyError, http.HttpError, tcp.NetLibDisconnect), e: if hasattr(e, "code"): cc.error = "%s: %s"%(e.code, e.msg) @@ -234,7 +240,7 @@ class ProxyHandler(tcp.BaseHandler): msg.append(" -> "+i) msg = "\n".join(msg) l = Log(msg) - self.channel.ask(l) + self.channel.tell(l) def find_cert(self, host, port, sni): if self.config.certfile: -- cgit v1.2.3 From 269780c57780d155c4d8bd95fcc2af2104effa5b Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 23 Feb 2013 16:34:59 +1300 Subject: Unit test dummy response functions. --- libmproxy/proxy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 6d476c7b..c8fac5f4 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -194,7 +194,8 @@ class ProxyHandler(tcp.BaseHandler): sc.rfile.first_byte_timestamp, utils.timestamp() ) response_reply = self.channel.ask(response) - # Not replying to the server invalidates the server connection, so we terminate. + # Not replying to the server invalidates the server + # connection, so we terminate. if response_reply == KILL: sc.terminate() -- cgit v1.2.3 From d0639e8925541bd6f6f386386c982d23b3828d3d Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 14:04:56 +1300 Subject: Handle server disconnects better. Server connections can be closed for legitimate reasons, like timeouts. If we've already pumped data over a server connection, we reconnect on error. If not, we treat it as a legitimate error and pass it on to the client. Fixes #85 --- libmproxy/proxy.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index c8fac5f4..088fe94c 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -117,8 +117,8 @@ class ServerConnectionPool: def get_connection(self, scheme, host, port): sc = self.conn if self.conn and (host, port) != (sc.host, sc.port): - sc.terminate() - self.conn = None + sc.terminate() + self.conn = None if not self.conn: try: self.conn = ServerConnection(self.config, host, port) @@ -127,6 +127,9 @@ class ServerConnectionPool: raise ProxyError(502, v) return self.conn + def del_connection(self, scheme, host, port): + self.conn = None + class ProxyHandler(tcp.BaseHandler): def __init__(self, config, connection, client_address, server, channel, server_version): @@ -181,14 +184,30 @@ class ProxyHandler(tcp.BaseHandler): scheme, host, port = self.config.reverse_proxy else: scheme, host, port = request.scheme, request.host, request.port - sc = self.server_conn_pool.get_connection(scheme, host, port) - sc.send(request) - sc.rfile.reset_timestamps() - httpversion, code, msg, headers, content = http.read_response( - sc.rfile, - request.method, - self.config.body_size_limit - ) + + # If we've already pumped a request over this connection, + # it's possible that the server has timed out. If this is + # the case, we want to reconnect without sending an error + # to the client. + while 1: + try: + sc = self.server_conn_pool.get_connection(scheme, host, port) + sc.send(request) + sc.rfile.reset_timestamps() + httpversion, code, msg, headers, content = http.read_response( + sc.rfile, + request.method, + self.config.body_size_limit + ) + except http.HttpErrorConnClosed, v: + if sc.requestcount > 1: + self.server_conn_pool.del_connection(scheme, host, port) + continue + else: + raise + else: + break + response = flow.Response( request, httpversion, code, msg, headers, content, sc.cert, sc.rfile.first_byte_timestamp, utils.timestamp() -- cgit v1.2.3 From 705559d65e5dc5883395efb85bacbf1459eb243c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 17:35:24 +1300 Subject: Refactor to prepare for SNI fixes. --- libmproxy/proxy.py | 99 +++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 50 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 088fe94c..d92e2da9 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -50,36 +50,13 @@ class ProxyConfig: self.certstore = certutils.CertStore(certdir) -class RequestReplayThread(threading.Thread): - 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.config, r.host, r.port) - server.connect(r.scheme) - server.send(r) - httpversion, code, msg, headers, content = http.read_response( - server.rfile, r.method, self.config.body_size_limit - ) - response = flow.Response( - self.flow.request, httpversion, code, msg, headers, content, server.cert - ) - self.channel.ask(response) - except (ProxyError, http.HttpError, tcp.NetLibError), v: - err = flow.Error(self.flow.request, str(v)) - self.channel.ask(err) - - class ServerConnection(tcp.TCPClient): def __init__(self, config, host, port): tcp.TCPClient.__init__(self, host, port) self.config = config self.requestcount = 0 - def connect(self, scheme): + def connect(self, scheme, sni): tcp.TCPClient.connect(self) if scheme == "https": clientcert = None @@ -88,7 +65,7 @@ class ServerConnection(tcp.TCPClient): if os.path.exists(path): clientcert = path try: - self.convert_to_ssl(clientcert=clientcert, sni=self.host) + self.convert_to_ssl(cert=clientcert, sni=sni) except tcp.NetLibError, v: raise ProxyError(400, str(v)) @@ -109,12 +86,35 @@ class ServerConnection(tcp.TCPClient): pass +class RequestReplayThread(threading.Thread): + 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.config, r.host, r.port) + server.connect(r.scheme, r.host) + server.send(r) + httpversion, code, msg, headers, content = http.read_response( + server.rfile, r.method, self.config.body_size_limit + ) + response = flow.Response( + self.flow.request, httpversion, code, msg, headers, content, server.cert + ) + self.channel.ask(response) + except (ProxyError, http.HttpError, tcp.NetLibError), v: + err = flow.Error(self.flow.request, str(v)) + self.channel.ask(err) + + class ServerConnectionPool: def __init__(self, config): self.config = config self.conn = None - def get_connection(self, scheme, host, port): + def get_connection(self, scheme, host, port, sni): sc = self.conn if self.conn and (host, port) != (sc.host, sc.port): sc.terminate() @@ -122,7 +122,7 @@ class ServerConnectionPool: if not self.conn: try: self.conn = ServerConnection(self.config, host, port) - self.conn.connect(scheme) + self.conn.connect(scheme, sni) except tcp.NetLibError, v: raise ProxyError(502, v) return self.conn @@ -190,18 +190,18 @@ class ProxyHandler(tcp.BaseHandler): # the case, we want to reconnect without sending an error # to the client. while 1: + sc = self.server_conn_pool.get_connection(scheme, host, port, host) + sc.send(request) + sc.rfile.reset_timestamps() try: - sc = self.server_conn_pool.get_connection(scheme, host, port) - sc.send(request) - sc.rfile.reset_timestamps() httpversion, code, msg, headers, content = http.read_response( sc.rfile, request.method, self.config.body_size_limit ) except http.HttpErrorConnClosed, v: + self.server_conn_pool.del_connection(scheme, host, port) if sc.requestcount > 1: - self.server_conn_pool.del_connection(scheme, host, port) continue else: raise @@ -324,25 +324,6 @@ class ProxyHandler(tcp.BaseHandler): self.rfile.first_byte_timestamp, utils.timestamp() ) - def read_request_reverse(self, client_conn): - line = self.get_line(self.rfile) - if line == "": - return None - scheme, host, port = self.config.reverse_proxy - r = http.parse_init_http(line) - if not r: - raise ProxyError(400, "Bad HTTP request line: %s"%repr(line)) - method, path, httpversion = r - headers = self.read_headers(authenticate=False) - content = http.read_http_body_request( - self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit - ) - return flow.Request( - client_conn, httpversion, host, port, "http", method, path, headers, content, - self.rfile.first_byte_timestamp, utils.timestamp() - ) - - def read_request_proxy(self, client_conn): line = self.get_line(self.rfile) if line == "": @@ -398,6 +379,24 @@ class ProxyHandler(tcp.BaseHandler): self.rfile.first_byte_timestamp, utils.timestamp() ) + def read_request_reverse(self, client_conn): + line = self.get_line(self.rfile) + if line == "": + return None + scheme, host, port = self.config.reverse_proxy + r = http.parse_init_http(line) + if not r: + raise ProxyError(400, "Bad HTTP request line: %s"%repr(line)) + method, path, httpversion = r + headers = self.read_headers(authenticate=False) + content = http.read_http_body_request( + self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit + ) + return flow.Request( + client_conn, httpversion, host, port, "http", method, path, headers, content, + self.rfile.first_byte_timestamp, utils.timestamp() + ) + def read_request(self, client_conn): self.rfile.reset_timestamps() if self.config.transparent_proxy: -- cgit v1.2.3 From 02578151410fff4b3c018303290e2f843e244a89 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 22:24:21 +1300 Subject: Significantly simplify server connection handling, and test. --- libmproxy/proxy.py | 66 +++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'libmproxy/proxy.py') diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index d92e2da9..7c229064 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -51,21 +51,22 @@ class ProxyConfig: class ServerConnection(tcp.TCPClient): - def __init__(self, config, host, port): + def __init__(self, config, scheme, host, port, sni): tcp.TCPClient.__init__(self, host, port) self.config = config + self.scheme, self.sni = scheme, sni self.requestcount = 0 - def connect(self, scheme, sni): + def connect(self): tcp.TCPClient.connect(self) - if scheme == "https": + if self.scheme == "https": clientcert = None if self.config.clientcerts: path = os.path.join(self.config.clientcerts, self.host.encode("idna")) + ".pem" if os.path.exists(path): clientcert = path try: - self.convert_to_ssl(cert=clientcert, sni=sni) + self.convert_to_ssl(cert=clientcert, sni=self.sni) except tcp.NetLibError, v: raise ProxyError(400, str(v)) @@ -94,8 +95,8 @@ class RequestReplayThread(threading.Thread): def run(self): try: r = self.flow.request - server = ServerConnection(self.config, r.host, r.port) - server.connect(r.scheme, r.host) + server = ServerConnection(self.config, r.scheme, r.host, r.port, r.host) + server.connect() server.send(r) httpversion, code, msg, headers, content = http.read_response( server.rfile, r.method, self.config.body_size_limit @@ -109,37 +110,40 @@ class RequestReplayThread(threading.Thread): self.channel.ask(err) -class ServerConnectionPool: - def __init__(self, config): - self.config = config - self.conn = None - - def get_connection(self, scheme, host, port, sni): - sc = self.conn - if self.conn and (host, port) != (sc.host, sc.port): - sc.terminate() - self.conn = None - if not self.conn: - try: - self.conn = ServerConnection(self.config, host, port) - self.conn.connect(scheme, sni) - except tcp.NetLibError, v: - raise ProxyError(502, v) - return self.conn - - def del_connection(self, scheme, host, port): - self.conn = None - - class ProxyHandler(tcp.BaseHandler): def __init__(self, config, connection, client_address, server, channel, server_version): self.channel, self.server_version = channel, server_version self.config = config - self.server_conn_pool = ServerConnectionPool(config) self.proxy_connect_state = None self.sni = None + self.server_conn = None tcp.BaseHandler.__init__(self, connection, client_address, server) + def get_server_connection(self, cc, scheme, host, port, sni): + sc = self.server_conn + if sc and (scheme, host, port, sni) != (sc.scheme, sc.host, sc.port, sc.sni): + sc.terminate() + self.server_conn = None + self.log( + cc, + "switching connection", [ + "%s://%s:%s (sni=%s) -> %s://%s:%s (sni=%s)"%( + scheme, host, port, sni, + sc.scheme, sc.host, sc.port, sc.sni + ) + ] + ) + if not self.server_conn: + try: + self.server_conn = ServerConnection(self.config, scheme, host, port, sni) + self.server_conn.connect() + except tcp.NetLibError, v: + raise ProxyError(502, v) + return self.server_conn + + def del_server_connection(self): + self.server_conn = None + def handle(self): cc = flow.ClientConnect(self.client_address) self.log(cc, "connect") @@ -190,7 +194,7 @@ class ProxyHandler(tcp.BaseHandler): # the case, we want to reconnect without sending an error # to the client. while 1: - sc = self.server_conn_pool.get_connection(scheme, host, port, host) + sc = self.get_server_connection(cc, scheme, host, port, host) sc.send(request) sc.rfile.reset_timestamps() try: @@ -200,7 +204,7 @@ class ProxyHandler(tcp.BaseHandler): self.config.body_size_limit ) except http.HttpErrorConnClosed, v: - self.server_conn_pool.del_connection(scheme, host, port) + self.del_server_connection() if sc.requestcount > 1: continue else: -- cgit v1.2.3