diff --git a/src/validation/httpvalidation.rs b/src/validation/httpvalidation.rs index ba2941b..866d83a 100644 --- a/src/validation/httpvalidation.rs +++ b/src/validation/httpvalidation.rs @@ -294,7 +294,10 @@ fn body_looks_like_html(body: &str, headers: &HeaderMap) -> bool { .unwrap_or(false); // ---- 2. early-body scan (<=1024 bytes) -------------------------------- - let probe = body[..body.len().min(1024)].to_ascii_lowercase(); + let probe = &body[..body.len().min(1024)]; + // Trim any leading whitespace so we still catch HTML that starts after newlines/indentation. + let trimmed = probe.trim_start_matches(|c: char| c.is_whitespace()); + let probe = trimmed.to_ascii_lowercase(); let body_looks_htmlish = probe.starts_with('<') && probe.contains("page"; + + assert!(body_looks_like_html(body, &headers)); + } + + #[test] + fn test_html_response_rejected_when_not_allowed() { + let matchers = vec![ResponseMatcher::StatusMatch { + r#type: "status-match".to_string(), + status: vec![StatusCode::OK], + match_all_status: false, + negative: false, + }]; + + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_TYPE, + HeaderValue::from_static("text/html; charset=utf-8"), + ); + + let body = "\nSign in"; + + let ok = validate_response(&matchers, body, &StatusCode::OK, &headers, false); + + assert!(!ok, "HTML responses should be rejected unless explicitly allowed"); + } }