Skip to content

Commit

Permalink
Add option to return various status codes rather than killing during …
Browse files Browse the repository at this point in the history
…server replay (#6465)

#### Description

Designed to satisfy the requirements of
#3489

Add `server_replay_404_extra` which behaves similarly to the kill flag,
but returns 404 responses rather than killing

#### Checklist

 - [x] I have updated tests where applicable.
 - [x] I have added an entry to the CHANGELOG.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
DKarandikar and autofix-ci[bot] committed Nov 8, 2023
1 parent 0c91733 commit 746537e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* Update savehar addon to handle scenarios where "path" key in cookie
attrs dict is missing.
([#6458](https://github.com/mitmproxy/mitmproxy/pull/6458), @pogzyb)
* Add `server_replay_extra` option to serverplayback to define behaviour
when replayable response is missing.
([#6465](https://github.com/mitmproxy/mitmproxy/pull/6465), @dkarandikar)


## 04 November 2023: mitmproxy 10.1.3
Expand Down
29 changes: 27 additions & 2 deletions mitmproxy/addons/serverplayback.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ def load(self, loader):
"server_replay_kill_extra",
bool,
False,
"Kill extra requests during replay (for which no replayable response was found).",
"Kill extra requests during replay (for which no replayable response was found)."
"[Deprecated, prefer to use server_replay_extra='kill']",
)
loader.add_option(
"server_replay_extra",
str,
"forward",
"Behaviour for extra requests during replay for which no replayable response was found. "
"Setting a numeric string value will return an empty HTTP response with the respective status code.",
choices=["forward", "kill", "204", "400", "404", "500"],
)
loader.add_option(
"server_replay_reuse",
Expand Down Expand Up @@ -230,6 +239,11 @@ def next_flow(self, flow: http.HTTPFlow) -> http.HTTPFlow | None:
return None

def configure(self, updated):
if ctx.options.server_replay_kill_extra:
logger.warning(
"server_replay_kill_extra has been deprecated, "
"please update your config to use server_replay_extra='kill'."
)
if ctx.options.server_replay_nopop: # pragma: no cover
logger.error(
"server_replay_nopop has been renamed to server_replay_reuse, please update your config."
Expand All @@ -252,10 +266,21 @@ def request(self, f: http.HTTPFlow) -> None:
response.refresh()
f.response = response
f.is_replay = "response"
elif ctx.options.server_replay_kill_extra:
elif (
ctx.options.server_replay_kill_extra
or ctx.options.server_replay_extra == "kill"
):
logging.warning(
"server_playback: killed non-replay request {}".format(
f.request.url
)
)
f.kill()
elif ctx.options.server_replay_extra != "forward":
logging.warning(
"server_playback: returned {} non-replay request {}".format(
ctx.options.server_replay_extra, f.request.url
)
)
f.response = http.Response.make(int(ctx.options.server_replay_extra))
f.is_replay = "response"
1 change: 1 addition & 0 deletions mitmproxy/tools/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def common_options(parser, opts):
group = parser.add_argument_group("Server Replay")
opts.make_parser(group, "server_replay", metavar="PATH", short="S")
opts.make_parser(group, "server_replay_kill_extra")
opts.make_parser(group, "server_replay_extra")
opts.make_parser(group, "server_replay_reuse")
opts.make_parser(group, "server_replay_refresh")

Expand Down
2 changes: 2 additions & 0 deletions mitmproxy/tools/console/statusbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ def get_status(self) -> list[tuple[str, str] | str]:
opts.append("norefresh")
if self.master.options.server_replay_kill_extra:
opts.append("killextra")
if self.master.options.server_replay_extra:
opts.append("replay-extra")
if not self.master.options.upstream_cert:
opts.append("no-upstream-cert")
if self.master.options.console_focus_follow:
Expand Down
39 changes: 39 additions & 0 deletions test/mitmproxy/addons/test_serverplayback.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,45 @@ async def test_server_playback_kill():
assert f.error


async def test_server_playback_kill_new_option():
s = serverplayback.ServerPlayback()
with taddons.context(s) as tctx:
tctx.configure(s, server_replay_refresh=True, server_replay_extra="kill")

f = tflow.tflow()
f.response = mitmproxy.test.tutils.tresp(content=f.request.content)
s.load_flows([f])

f = tflow.tflow()
f.request.host = "nonexistent"
await tctx.cycle(s, f)
assert f.error


@pytest.mark.parametrize(
"option,status",
[
("204", 204),
("400", 400),
("404", 404),
("500", 500),
],
)
async def test_server_playback_404(option, status):
s = serverplayback.ServerPlayback()
with taddons.context(s) as tctx:
tctx.configure(s, server_replay_refresh=True, server_replay_extra=option)

f = tflow.tflow()
f.response = mitmproxy.test.tutils.tresp(content=f.request.content)
s.load_flows([f])

f = tflow.tflow()
f.request.host = "nonexistent"
s.request(f)
assert f.response.status_code == status


def test_server_playback_response_deleted():
"""
The server playback addon holds references to flows that can be modified by the user in the meantime.
Expand Down
2 changes: 1 addition & 1 deletion test/mitmproxy/tools/console/test_statusbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async def test_statusbar(console, monkeypatch):
anticomp=True,
showhost=True,
server_replay_refresh=False,
server_replay_kill_extra=True,
server_replay_extra="kill",
upstream_cert=False,
stream_large_bodies="3m",
mode=["transparent"],
Expand Down
2 changes: 2 additions & 0 deletions web/src/js/ducks/_options_gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface OptionsState {
scripts: string[];
server: boolean;
server_replay: string[];
server_replay_extra: string;
server_replay_ignore_content: boolean;
server_replay_ignore_host: boolean;
server_replay_ignore_params: string[];
Expand Down Expand Up @@ -146,6 +147,7 @@ export const defaultState: OptionsState = {
scripts: [],
server: true,
server_replay: [],
server_replay_extra: "forward",
server_replay_ignore_content: false,
server_replay_ignore_host: false,
server_replay_ignore_params: [],
Expand Down

0 comments on commit 746537e

Please sign in to comment.