110 lines
4.0 KiB
Rust
110 lines
4.0 KiB
Rust
mod tests {
|
|
use super::*;
|
|
#[test]
|
|
fn transformations_preserve_distinct_set_cookie_fields() {
|
|
let source = r#"{"request":[],"response":[{"op":"remove","name":"server"},{"op":"set","name":"x-test","value":"one"},{"op":"append","name":"x-test","value":"two"},{"op":"append","name":"set-cookie","value":"b=2"}]}"#;
|
|
let rules: HeaderRules = serde_json::from_str(source).unwrap();
|
|
let compiled = rules.compile().unwrap();
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert("server", "upstream".parse().unwrap());
|
|
headers.append("set-cookie", "a=1".parse().unwrap());
|
|
apply(&mut headers, &compiled.response);
|
|
assert!(!headers.contains_key("server"));
|
|
assert_eq!(headers.get_all("x-test").iter().count(), 2);
|
|
assert_eq!(headers.get_all("set-cookie").iter().count(), 2);
|
|
}
|
|
#[test]
|
|
fn transport_identity_and_crlf_are_rejected() {
|
|
for name in [
|
|
"Host",
|
|
"Connection",
|
|
"Content-Length",
|
|
"x-forwarded-for",
|
|
"Upgrade",
|
|
"X-RustProxy-Backend",
|
|
"X-Rust-Proxy-Backend",
|
|
"X-RustProxy-Backend-Time",
|
|
"X-Rust-Proxy-Backend-Time",
|
|
] {
|
|
let rules = HeaderRules {
|
|
request: vec![Rule {
|
|
op: Operation::Set,
|
|
name: name.into(),
|
|
value: Some("x".into()),
|
|
}],
|
|
response: vec![],
|
|
};
|
|
assert!(rules.compile().is_err(), "{name}");
|
|
let response_rules = HeaderRules { request: vec![], response: rules.request };
|
|
assert!(response_rules.compile().is_err(), "response {name}");
|
|
}
|
|
let rules = HeaderRules {
|
|
request: vec![Rule {
|
|
op: Operation::Set,
|
|
name: "x-test".into(),
|
|
value: Some("hello\r\ninjected: yes".into()),
|
|
}],
|
|
response: vec![],
|
|
};
|
|
assert!(rules.compile().is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn response_age_is_allowed_but_applied_only_at_wire_stage() {
|
|
let request_age = HeaderRules {
|
|
request: vec![Rule {
|
|
op: Operation::Set,
|
|
name: "Age".into(),
|
|
value: Some("7".into()),
|
|
}],
|
|
response: vec![],
|
|
};
|
|
let request_compiled = request_age.compile().unwrap();
|
|
let mut request_headers = HeaderMap::new();
|
|
apply(&mut request_headers, &request_compiled.request);
|
|
assert_eq!(request_headers["age"], "7");
|
|
|
|
let response_age = HeaderRules {
|
|
request: vec![],
|
|
response: vec![Rule {
|
|
op: Operation::Remove,
|
|
name: "Age".into(),
|
|
value: None,
|
|
}],
|
|
};
|
|
let compiled = response_age.compile().unwrap();
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert("age", HeaderValue::from_static("42"));
|
|
apply(&mut headers, &compiled.response);
|
|
assert_eq!(headers["age"], "42");
|
|
apply_wire_age(&mut headers, &compiled.response);
|
|
assert!(!headers.contains_key("age"));
|
|
}
|
|
|
|
#[test]
|
|
fn response_age_keeps_0266_rule_compatibility() {
|
|
let rules = HeaderRules {
|
|
request: vec![],
|
|
response: vec![
|
|
Rule {
|
|
op: Operation::Set,
|
|
name: "age".into(),
|
|
value: Some("custom".into()),
|
|
},
|
|
Rule {
|
|
op: Operation::Append,
|
|
name: "age".into(),
|
|
value: Some("7".into()),
|
|
},
|
|
],
|
|
};
|
|
let compiled = rules.compile().unwrap();
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert("age", HeaderValue::from_static("42"));
|
|
apply(&mut headers, &compiled.response);
|
|
assert_eq!(headers["age"], "42");
|
|
apply_wire_age(&mut headers, &compiled.response);
|
|
assert_eq!(headers.get_all("age").iter().count(), 2);
|
|
}
|
|
}
|