aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/protocol
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2014-10-26 17:58:36 +1300
committerAldo Cortesi <aldo@nullcube.com>2014-10-26 17:58:36 +1300
commit16654ad6a4ba4f12287d5707dafe3794b6e33fb8 (patch)
treec4bb04d3f8070272589775fdc53fc0f40ce63340 /libmproxy/protocol
parent7aee9a7c311e755147b398b8ba0b44aaec40eaf7 (diff)
downloadmitmproxy-16654ad6a4ba4f12287d5707dafe3794b6e33fb8.tar.gz
mitmproxy-16654ad6a4ba4f12287d5707dafe3794b6e33fb8.tar.bz2
mitmproxy-16654ad6a4ba4f12287d5707dafe3794b6e33fb8.zip
Fix crash while streaming
Found using fuzzing. Reproduction with pathoc, given "mitmproxy -s" and pathod running on 9999: get:'http://localhost:9999/p/':s'200:b\'foo\':h\'Content-Length\'=\'3\'':i58,'\x1a':r return flow.FlowMaster.run(self) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 111, in run self.tick(self.masterq, 0.01) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 613, in tick return controller.Master.tick(self, q, timeout) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 101, in tick self.handle(*msg) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 118, in handle m(obj) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 738, in handle_responseheaders self.stream_large_bodies.run(f, False) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 155, in run r.headers, is_request, flow.request.method, code File "/Users/aldo/mitmproxy/mitmproxy/netlib/http.py", line 401, in expected_http_body_size raise HttpError(400 if is_request else 502, "Invalid content-length header: %s" % headers["content-length"]) netlib.http.HttpError: Invalid content-length header: ['\x1a3']
Diffstat (limited to 'libmproxy/protocol')
-rw-r--r--libmproxy/protocol/http.py40
1 files changed, 27 insertions, 13 deletions
diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py
index 9542cc81..e81c7640 100644
--- a/libmproxy/protocol/http.py
+++ b/libmproxy/protocol/http.py
@@ -18,6 +18,10 @@ HDR_FORM_URLENCODED = "application/x-www-form-urlencoded"
CONTENT_MISSING = 0
+class KillSignal(Exception):
+ pass
+
+
def get_line(fp):
"""
Get a line, possibly preceded by a blank.
@@ -1001,19 +1005,21 @@ class HTTPHandler(ProtocolHandler):
# call the appropriate script hook - this is an opportunity for an
# inline script to set flow.stream = True
- self.c.channel.ask("responseheaders", flow)
-
- # now get the rest of the request body, if body still needs to be read
- # but not streaming this response
- if flow.response.stream:
- flow.response.content = CONTENT_MISSING
+ flow = self.c.channel.ask("responseheaders", flow)
+ if flow == KILL:
+ raise KillSignal
else:
- flow.response.content = http.read_http_body(
- self.c.server_conn.rfile, flow.response.headers,
- self.c.config.body_size_limit,
- flow.request.method, flow.response.code, False
- )
- flow.response.timestamp_end = utils.timestamp()
+ # now get the rest of the request body, if body still needs to be
+ # read but not streaming this response
+ if flow.response.stream:
+ flow.response.content = CONTENT_MISSING
+ else:
+ flow.response.content = http.read_http_body(
+ self.c.server_conn.rfile, flow.response.headers,
+ self.c.config.body_size_limit,
+ flow.request.method, flow.response.code, False
+ )
+ flow.response.timestamp_end = utils.timestamp()
def handle_flow(self):
flow = HTTPFlow(self.c.client_conn, self.c.server_conn, self.live)
@@ -1092,8 +1098,16 @@ class HTTPHandler(ProtocolHandler):
flow.live.restore_server()
return True # Next flow please.
- except (HttpAuthenticationError, http.HttpError, proxy.ProxyError, tcp.NetLibError), e:
+ except (
+ HttpAuthenticationError,
+ http.HttpError,
+ proxy.ProxyError,
+ tcp.NetLibError,
+ ), e:
self.handle_error(e, flow)
+ except KillSignal:
+ self.c.log("Connection killed", "info")
+ flow.live = None
finally:
flow.live = None # Connection is not live anymore.
return False