Skip to content

Commit 72de95c

Browse files
authored
fix(uptime): only download body bytes if the assertion needs them (#483)
1 parent 2f7727b commit 72de95c

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

src/assertions/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,35 @@ pub struct Assertion {
99
pub(crate) root: Op,
1010
}
1111

12+
impl Assertion {
13+
fn requires_body_impl(op: &Op) -> bool {
14+
match op {
15+
Op::And { children } => children.iter().any(Assertion::requires_body_impl),
16+
Op::Or { children } => children.iter().any(Assertion::requires_body_impl),
17+
Op::Not { operand } => Assertion::requires_body_impl(operand),
18+
Op::StatusCodeCheck {
19+
value: _,
20+
operator: _,
21+
} => false,
22+
Op::JsonPath {
23+
value: _,
24+
operator: _,
25+
operand: _,
26+
} => true,
27+
Op::HeaderCheck {
28+
key_op: _,
29+
key_operand: _,
30+
value_op: _,
31+
value_operand: _,
32+
} => false,
33+
}
34+
}
35+
36+
pub fn requires_body(&self) -> bool {
37+
Assertion::requires_body_impl(&self.root)
38+
}
39+
}
40+
1241
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
1342
#[serde(tag = "cmp", rename_all = "snake_case")]
1443
#[derive(Default)]

src/checker/reqwest_checker.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,11 @@ impl Checker for ReqwestChecker {
531531
|| (self.response_capture_enabled && check.get_config().capture_response_on_failure);
532532

533533
// Read body bytes if we have an assertion OR if we should capture on failure.
534-
let needs_body_for_assertion = check.get_config().assertion.is_some();
534+
let needs_body_for_assertion = if let Some(assertion) = &check.get_config().assertion {
535+
assertion.requires_body()
536+
} else {
537+
false
538+
};
535539
let body_bytes = if (needs_body_for_assertion || should_capture) && response.is_ok() {
536540
let Ok((resp, _req_id)) = &mut response else {
537541
unreachable!("enclosing if-statement means this cannot happen");
@@ -718,7 +722,7 @@ impl Checker for ReqwestChecker {
718722

719723
#[cfg(test)]
720724
mod tests {
721-
use crate::assertions;
725+
use crate::assertions::{self, Assertion};
722726
use crate::check_executor::ScheduledCheck;
723727
use crate::checker::Checker;
724728
use crate::config_store::Tick;
@@ -1020,6 +1024,58 @@ mod tests {
10201024
mock.assert();
10211025
}
10221026

1027+
#[tokio::test]
1028+
async fn test_jsonpath_body_downloads() {
1029+
let server = MockServer::start();
1030+
let checker = ReqwestChecker::new_internal(
1031+
Options {
1032+
validate_url: false,
1033+
disable_connection_reuse: true,
1034+
response_capture_enabled: false, // disabled
1035+
..Default::default()
1036+
},
1037+
assertions::cache::Cache::new(),
1038+
);
1039+
1040+
let mock = server.mock(|when, then| {
1041+
when.method(Method::GET)
1042+
.path("/no-head")
1043+
.header_exists("sentry-trace")
1044+
.header("User-Agent", UPTIME_USER_AGENT.to_string());
1045+
then.status(200).body("{ \"foo\":\"bar\"}");
1046+
});
1047+
1048+
let config = CheckConfig {
1049+
url: server.url("/no-head").to_string(),
1050+
assertion: Assertion {
1051+
root: assertions::Op::And {
1052+
children: vec![assertions::Op::Or {
1053+
children: vec![assertions::Op::Not {
1054+
operand: assertions::Op::JsonPath {
1055+
value: "$.foo".to_owned(),
1056+
operator: assertions::Comparison::Equals,
1057+
operand: assertions::JSONPathOperand::Literal {
1058+
value: "baz".to_owned(),
1059+
},
1060+
}
1061+
.into(),
1062+
}],
1063+
}],
1064+
},
1065+
}
1066+
.into(),
1067+
..Default::default()
1068+
};
1069+
1070+
let tick = make_tick();
1071+
let check = ScheduledCheck::new_for_test(tick, config);
1072+
let result = checker.check_url(&check, "us-west").await;
1073+
1074+
assert_eq!(result.status, CheckStatus::Success);
1075+
1076+
mock.assert();
1077+
}
1078+
10231079
#[tokio::test]
10241080
async fn test_response_capture_forced() {
10251081
let server = MockServer::start();

0 commit comments

Comments
 (0)