104 lines
4.1 KiB
Rust
104 lines
4.1 KiB
Rust
use super::*;
|
|
|
|
#[test]
|
|
fn body_budgets_timeouts_invalid_messages_and_recovery_are_bounded() {
|
|
runtime().run(async |scope| {
|
|
let listener = net::listen("127.0.0.1", 0, scope).await.unwrap();
|
|
let port = listener.port().unwrap();
|
|
let incoming = listener.clone();
|
|
let server = scope.spawn(move |child| async move {
|
|
let limits = Limits { body_bytes: 4, timeout_ms: 100, ..Limits::default() };
|
|
http::serve::<_, _, false>(&incoming, &limits, &child, route).await
|
|
}).unwrap();
|
|
scope.blocking(move || {
|
|
let query_only = format!("GET ?{} HTTP/1.1\r\nHost: t\r\n\r\n", "a".repeat(8163));
|
|
for (message, expected) in [
|
|
("POST /echo HTTP/1.1\r\nHost: fixture.test\r\nContent-Length: 5\r\n\r\n12345", 413),
|
|
("POST /echo HTTP/1.1\r\nHost: fixture.test\r\nContent-Length: 4\r\n\r\n1", 408),
|
|
("GET /wait HTTP/1.1\r\nHost: fixture.test\r\n\r\n", 504),
|
|
("GET /echo HTTP/1.1\r\nHost: one\r\nHost: two\r\n\r\n", 400),
|
|
(query_only.as_str(), 400),
|
|
] {
|
|
let mut stream = connect(port);
|
|
stream.get_mut().write_all(message.as_bytes()).unwrap();
|
|
assert_eq!(read_response(&mut stream, false).0, expected);
|
|
assert_eq!(stream.read(&mut [0]).unwrap(), 0);
|
|
}
|
|
let mut stream = connect(port);
|
|
stream.get_mut().write_all(b"GET / HTTP/1.1\r\nHost:").unwrap();
|
|
assert_eq!(stream.read(&mut [0]).unwrap(), 0);
|
|
}).await.unwrap();
|
|
let response = http::send("127.0.0.1", port, request("/echo", b"ok"), &Limits::default()).await.unwrap();
|
|
assert_eq!(response.body.as_ref(), b"ok");
|
|
listener.close().unwrap();
|
|
server.wait().await.unwrap().unwrap();
|
|
}).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn outgoing_contracts_reject_framing_injection_and_bad_limits() {
|
|
runtime()
|
|
.run(async |_| {
|
|
for header in [
|
|
Header {
|
|
name: "Content-Length".into(),
|
|
value: b"0".to_vec().into(),
|
|
},
|
|
Header {
|
|
name: "Transfer-Encoding".into(),
|
|
value: b"chunked".to_vec().into(),
|
|
},
|
|
Header {
|
|
name: "x-test".into(),
|
|
value: b"a\r\nb".to_vec().into(),
|
|
},
|
|
] {
|
|
let mut message = request("/", b"");
|
|
message.headers.push(header);
|
|
let error = http::send("127.0.0.1", 1, message, &Limits::default())
|
|
.await
|
|
.unwrap_err();
|
|
assert!(!error.contains("connection failed"), "{error}");
|
|
}
|
|
for limits in [
|
|
Limits {
|
|
header_bytes: 0,
|
|
..Limits::default()
|
|
},
|
|
Limits {
|
|
body_bytes: -1,
|
|
..Limits::default()
|
|
},
|
|
Limits {
|
|
timeout_ms: 0,
|
|
..Limits::default()
|
|
},
|
|
Limits {
|
|
connections: 65537,
|
|
..Limits::default()
|
|
},
|
|
] {
|
|
assert!(
|
|
http::send("127.0.0.1", 1, request("/", b""), &limits)
|
|
.await
|
|
.is_err()
|
|
);
|
|
}
|
|
let long_target = format!("/{}", "x".repeat(8192));
|
|
for (method, target) in [
|
|
("CONNECT", "/"),
|
|
("GET", "http://example.test/"),
|
|
("GET", "/#fragment"),
|
|
("GET", long_target.as_str()),
|
|
] {
|
|
let mut message = request(target, b"");
|
|
message.method = method.into();
|
|
let error = http::send("127.0.0.1", 1, message, &Limits::default())
|
|
.await
|
|
.unwrap_err();
|
|
assert!(!error.contains("connection failed"), "{error}");
|
|
}
|
|
})
|
|
.unwrap();
|
|
}
|