From c9be57b6828ac06e7ec105cba15560fb2c83030e Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 27 Jul 2014 03:28:23 +0200 Subject: fix #313 --- libmproxy/protocol/http.py | 10 ++++++++-- test/test_protocol_http.py | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index f671816f..21fc2798 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -930,9 +930,14 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin): if (http.connection_close(flow.request.httpversion, flow.request.headers) or http.connection_close(flow.response.httpversion, flow.response.headers)): - return False + if flow.request.form_in == "authority" and flow.response.code == 200: + # Workaround for https://github.com/mitmproxy/mitmproxy/issues/313: + # Some proxies (e.g. Charles) send a CONNECT response with HTTP/1.0 and no Content-Length header + pass + else: + return False - if flow.request.form_in == "authority": + if flow.request.form_in == "authority" and flow.response.code == 200: self.ssl_upgrade() # If the user has changed the target server on this connection, @@ -1039,6 +1044,7 @@ class HTTPHandler(ProtocolHandler, TemporaryServerChangeMixin): 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' + + 'Content-Length: 0\r\n' + ('Proxy-agent: %s\r\n' % self.c.server_version) + '\r\n' ) diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index 4026e79a..451b7b5d 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -54,7 +54,6 @@ class TestHTTPRequest: r = tutils.treq() tutils.raises("Invalid request form", r._assemble, "antiauthority") - def test_set_url(self): r = tutils.treq_absolute() r.set_url("https://otheraddress:42/ORLY") @@ -127,6 +126,21 @@ class TestProxyChainingSSL(tservers.HTTPChainProxyTest): # request from chain[1] to proxy assert self.proxy.tmaster.state.flow_count() == 1 # request from chain[0] (regular proxy doesn't store CONNECTs) + def test_closing_connect_response(self): + """ + https://github.com/mitmproxy/mitmproxy/issues/313 + """ + def handle_request(r): + r.httpversion = (1,0) + del r.headers["Content-Length"] + r.reply() + _handle_request = self.chain[0].tmaster.handle_request + self.chain[0].tmaster.handle_request = handle_request + try: + assert self.pathoc().request("get:/p/418").status_code == 418 + finally: + self.chain[0].tmaster.handle_request = _handle_request + class TestProxyChainingSSLReconnect(tservers.HTTPChainProxyTest): ssl = True -- cgit v1.2.3