This commit is contained in:
Syed Osama Ali Shah 2026-10-14 20:05:43 +00:00 • committed by GitHub
commit f70a13c23d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 87 additions and 0 deletions

View file

@ -309,6 +309,18 @@ def apply_modifications(
headers.update(modifications["headers"])
if "body" in modifications:
body = modifications["body"]
# Replacing the body invalidates any carried-over Content-Length.
# Drop it (case-insensitively) so build_raw_request recomputes the
# correct length for the new body — unless the caller deliberately
# set Content-Length in this call's header modifications.
explicit_cl = {k.title() for k in modifications.get("headers", {})}
if "Content-Length" not in explicit_cl:
for key in [k for k in headers if k.title() == "Content-Length"]:
del headers[key]
# build_raw_request only auto-adds Content-Length for a non-empty
# body, so an empty replacement body needs it set explicitly.
if body == "":
headers["Content-Length"] = "0"
if "cookies" in modifications:
cookies: dict[str, str] = {}
if headers.get("Cookie"):

View file

@ -0,0 +1,75 @@
"""Tests for raw-request building in the Caido proxy helper."""
from __future__ import annotations
from strix.tools.proxy.caido_api import apply_modifications, build_raw_request
def _content_length(raw: bytes) -> str | None:
for line in raw.decode("utf-8").split("\r\n"):
if line.lower().startswith("content-length:"):
return line.split(":", 1)[1].strip()
return None
def test_body_replacement_recomputes_content_length() -> None:
components = {
"method": "POST",
"headers": {"Host": "x.test", "Content-Length": "3"},
"body": "old",
}
new_body = "this is the new and much longer body!"
result = apply_modifications(components, {"body": new_body}, "http://x.test/submit")
_conn, raw = build_raw_request(
method=result["method"],
url=result["url"],
headers=result["headers"],
body=result["body"],
)
assert _content_length(raw) == str(len(new_body.encode("utf-8")))
def test_explicit_content_length_override_is_preserved() -> None:
components = {
"method": "POST",
"headers": {"Host": "x.test", "Content-Length": "3"},
"body": "old",
}
result = apply_modifications(
components,
{"body": "new body", "headers": {"Content-Length": "999"}},
"http://x.test/",
)
_conn, raw = build_raw_request(
method=result["method"],
url=result["url"],
headers=result["headers"],
body=result["body"],
)
assert _content_length(raw) == "999"
def test_no_body_modification_keeps_content_length() -> None:
components = {
"method": "POST",
"headers": {"Host": "x.test", "Content-Length": "3"},
"body": "old",
}
result = apply_modifications(components, {"headers": {"X-Test": "1"}}, "http://x.test/")
assert result["headers"].get("Content-Length") == "3"
def test_empty_body_replacement_sets_content_length_zero() -> None:
components = {
"method": "POST",
"headers": {"Host": "x.test", "Content-Length": "3"},
"body": "old",
}
result = apply_modifications(components, {"body": ""}, "http://x.test/")
_conn, raw = build_raw_request(
method=result["method"],
url=result["url"],
headers=result["headers"],
body=result["body"],
)
assert _content_length(raw) == "0"