aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/cmdline.py27
-rw-r--r--libmproxy/flow.py8
-rw-r--r--libmproxy/protocol/http.py40
3 files changed, 50 insertions, 25 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index 83eab7ee..4a3b5a48 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -248,14 +248,18 @@ def common_options(parser):
"--stream",
action="store", dest="stream_large_bodies", default=None,
metavar="SIZE",
- help="Stream data to the client if response body exceeds the given threshold. "
- "If streamed, the body will not be stored in any way. Understands k/m/g suffixes, i.e. 3m for 3 megabytes."
+ help="""
+ Stream data to the client if response body exceeds the given threshold.
+ If streamed, the body will not be stored in any way. Understands k/m/g
+ suffixes, i.e. 3m for 3 megabytes.
+ """
)
group = parser.add_argument_group("Proxy Options")
- # We could make a mutually exclusive group out of -R, -U, -T, but we don't do that because
- # - --upstream-server should be in that group as well, but it's already in a different group.
- # - our own error messages are more helpful
+ # We could make a mutually exclusive group out of -R, -U, -T, but we don't
+ # do that because - --upstream-server should be in that group as well, but
+ # it's already in a different group. - our own error messages are more
+ # helpful
group.add_argument(
"-b",
action="store", type=str, dest="addr", default='',
@@ -265,11 +269,14 @@ def common_options(parser):
"-I", "--ignore",
action="append", type=str, dest="ignore_hosts", default=[],
metavar="HOST",
- help="Ignore host and forward all traffic without processing it. "
- "In transparent mode, it is recommended to use an IP address (range), not the hostname. "
- "In regular mode, only SSL traffic is ignored and the hostname should be used. "
- "The supplied value is interpreted as a regular expression and matched on the ip or the hostname. "
- "Can be passed multiple times. "
+ help="""
+ Ignore host and forward all traffic without processing it. In
+ transparent mode, it is recommended to use an IP address (range),
+ not the hostname. In regular mode, only SSL traffic is ignored and
+ the hostname should be used. The supplied value is interpreted as a
+ regular expression and matched on the ip or the hostname. Can be
+ passed multiple times.
+ """
)
group.add_argument(
"--tcp",
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 6a24cc63..6136ec1c 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -738,8 +738,12 @@ class FlowMaster(controller.Master):
def handle_responseheaders(self, f):
self.run_script_hook("responseheaders", f)
- if self.stream_large_bodies:
- self.stream_large_bodies.run(f, False)
+ try:
+ if self.stream_large_bodies:
+ self.stream_large_bodies.run(f, False)
+ except netlib.http.HttpError:
+ f.reply(protocol.KILL)
+ return
f.reply()
return f
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