mod http_invalidation_tests { use super::*; #[test] fn default_deny_and_strict_ipv4_ipv6_cidr_validation() { let mut cache = Settings::default(); assert!(!cache.permits_http_invalidation("127.0.0.1".parse().unwrap())); cache.http_invalidation_allowed_cidrs = vec!["192.0.2.42".into(), "2001:db8:10::/64".into()]; cache.validate().unwrap(); assert!(cache.permits_http_invalidation("192.0.2.42".parse().unwrap())); assert!(!cache.permits_http_invalidation("192.0.2.43".parse().unwrap())); assert!(cache.permits_http_invalidation("2001:db8:10::1".parse().unwrap())); assert!(!cache.permits_http_invalidation("2001:db8:11::1".parse().unwrap())); for invalid in ["0.0.0.0/0", "::/0", "127.0.0.1; 8.8.8.8", "not-an-ip", "10.0.0.0/33"] { cache.http_invalidation_allowed_cidrs = vec![invalid.into()]; assert!(cache.validate().is_err(), "must reject {invalid}"); } cache.http_invalidation_allowed_cidrs = vec!["192.0.2.42".into(), "192.0.2.42/32".into()]; assert!(cache.validate().is_err(), "duplicate ranges"); let old: Settings = serde_json::from_value(serde_json::json!({})).unwrap(); assert!(old.http_invalidation_allowed_cidrs.is_empty()); } #[test] fn url_qualified_invalidation_matches_only_the_requested_scheme_and_host() { let requested = InvalidationRequest { operation: InvalidationOperation::Purge, selector: InvalidationSelector::Exact, value: "https://a.example/a?v=1".into(), host: Some("a.example".into()), vhost: Some("frontend-1".into()), ttl_seconds: None, confirm_wide: false, }; let matcher = normalized_matcher(&requested).unwrap(); assert_eq!(matcher.value, "/a?v=1"); assert_eq!(matcher.scheme.as_deref(), Some("https")); assert!(host_matches(&matcher, "https", "a.example", "a.example")); assert!(!host_matches(&matcher, "http", "a.example", "a.example")); assert!(!host_matches(&matcher, "https", "b.example", "b.example")); } }