Skip to content

Commit

Permalink
Stream large bodies warn with modify body (#6514)
Browse files Browse the repository at this point in the history
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Hils <git@maximilianhils.com>
  • Loading branch information
3 people committed Dec 5, 2023
1 parent ba84b6b commit 81fc802
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,8 @@
([#5084](https://github.com/mitmproxy/mitmproxy/pull/5084), @Speedlulu)
* Scripts with relative paths are now loaded relative to the config file and not where the command is ran
([#4860](https://github.com/mitmproxy/mitmproxy/pull/4860), @Speedlulu)
* Enhance documentation and add alert log messages when stream_large_bodies and modify_body are set
([#6514](https://github.com/mitmproxy/mitmproxy/pull/6514), @rosydawn6)


## 14 November 2023: mitmproxy 10.1.5
Expand Down
8 changes: 5 additions & 3 deletions docs/src/content/overview-features.md
Expand Up @@ -205,7 +205,9 @@ if a modify hook is triggered on server response, the replacement is
only run on the Response object leaving the Request intact. You control
whether the hook triggers on the request, response or both using the
filter pattern. If you need finer-grained control than this, it's simple
to create a script using the replacement API on Flow components.
to create a script using the replacement API on Flow components. Body
modifications have no effect on streamed bodies. See
[Streaming]({{< relref "#streaming" >}}) for more detail.

#### Examples

Expand Down Expand Up @@ -359,8 +361,8 @@ indicated manipulations on it, and then send the message on to the other party.
This can be problematic when downloading or uploading large files. When
streaming is enabled, message bodies are not buffered on the proxy but instead
sent directly to the server/client. This currently means that the message body
will not be accessible within mitmproxy. HTTP headers are still fully buffered before
being sent.
will not be accessible within mitmproxy, and body modifications will have no
effect. HTTP headers are still fully buffered before being sent.

Request/response streaming is enabled by specifying a size cutoff in the
`stream_large_bodies` option.
Expand Down
15 changes: 15 additions & 0 deletions mitmproxy/addons/modifybody.py
Expand Up @@ -6,6 +6,9 @@
from mitmproxy import exceptions
from mitmproxy.addons.modifyheaders import ModifySpec
from mitmproxy.addons.modifyheaders import parse_modify_spec
from mitmproxy.log import ALERT

logger = logging.getLogger(__name__)


class ModifyBody:
Expand Down Expand Up @@ -37,6 +40,18 @@ def configure(self, updated):

self.replacements.append(spec)

stream_and_modify_conflict = (
ctx.options.modify_body
and ctx.options.stream_large_bodies
and ("modify_body" in updated or "stream_large_bodies" in updated)
)
if stream_and_modify_conflict:
logger.log(
ALERT,
"Both modify_body and stream_large_bodies are active. "
"Streamed bodies will not be modified.",
)

def request(self, flow):
if flow.response or flow.error or not flow.live:
return
Expand Down
5 changes: 3 additions & 2 deletions mitmproxy/addons/proxyserver.py
Expand Up @@ -150,8 +150,9 @@ def load(self, loader):
None,
"""
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.
threshold. If streamed, the body will not be stored in any way,
and such responses cannot be modified. Understands k/m/g
suffixes, i.e. 3m for 3 megabytes.
""",
)
loader.add_option(
Expand Down
8 changes: 8 additions & 0 deletions test/mitmproxy/addons/test_modifybody.py
@@ -1,6 +1,7 @@
import pytest

from mitmproxy.addons import modifybody
from mitmproxy.addons import proxyserver
from mitmproxy.test import taddons
from mitmproxy.test import tflow
from mitmproxy.test.tutils import tresp
Expand All @@ -14,6 +15,13 @@ def test_configure(self):
with pytest.raises(Exception, match="Cannot parse modify_body"):
tctx.configure(mb, modify_body=["/"])

def test_warn_conflict(self, caplog):
caplog.set_level("DEBUG")
mb = modifybody.ModifyBody()
with taddons.context(mb, proxyserver.Proxyserver()) as tctx:
tctx.configure(mb, stream_large_bodies="3m", modify_body=["one/two/three"])
assert "Streamed bodies will not be modified" in caplog.text

def test_simple(self):
mb = modifybody.ModifyBody()
with taddons.context(mb) as tctx:
Expand Down

0 comments on commit 81fc802

Please sign in to comment.