Limit send flow control bug to window_size (#78)
Senders could set the available capacity greater than the current `window_size`. This caused a panic when the sender attempted to send more than the receiver could accept.
This commit is contained in:
committed by
Oliver Gould
parent
9448a19408
commit
93925e6d1f
@@ -539,3 +539,83 @@ fn recv_window_update_on_stream_closed_by_data_frame() {
|
||||
let _ = h2.join(srv)
|
||||
.wait().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserved_capacity_assigned_in_multi_window_updates() {
|
||||
let _ = ::env_logger::init();
|
||||
let (io, srv) = mock::new();
|
||||
|
||||
let h2 = Client::handshake(io).unwrap()
|
||||
.and_then(|mut h2| {
|
||||
let request = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri("https://http2.akamai.com/")
|
||||
.body(()).unwrap();
|
||||
|
||||
let mut stream = h2.request(request, false).unwrap();
|
||||
|
||||
// Consume the capacity
|
||||
let payload = vec![0; frame::DEFAULT_INITIAL_WINDOW_SIZE as usize];
|
||||
stream.send_data(payload.into(), false).unwrap();
|
||||
|
||||
// Reserve more data than we want
|
||||
stream.reserve_capacity(10);
|
||||
|
||||
h2.drive(util::wait_for_capacity(stream, 5))
|
||||
})
|
||||
.and_then(|(h2, mut stream)| {
|
||||
stream.send_data("hello".into(), false).unwrap();
|
||||
stream.send_data("world".into(), true).unwrap();
|
||||
|
||||
h2.drive(GetResponse { stream: Some(stream) })
|
||||
})
|
||||
.and_then(|(h2, (response, _))| {
|
||||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
|
||||
// Wait for the connection to close
|
||||
h2.unwrap()
|
||||
})
|
||||
;
|
||||
|
||||
let srv = srv.assert_client_handshake().unwrap()
|
||||
.recv_settings()
|
||||
.recv_frame(
|
||||
frames::headers(1)
|
||||
.request("POST", "https://http2.akamai.com/")
|
||||
)
|
||||
.recv_frame(frames::data(1, vec![0u8; 16_384]))
|
||||
.recv_frame(frames::data(1, vec![0u8; 16_384]))
|
||||
.recv_frame(frames::data(1, vec![0u8; 16_384]))
|
||||
.recv_frame(frames::data(1, vec![0u8; 16_383]))
|
||||
.idle_ms(100)
|
||||
// Increase the connection window
|
||||
.send_frame(
|
||||
frames::window_update(0, 10))
|
||||
// Incrementally increase the stream window
|
||||
.send_frame(
|
||||
frames::window_update(1, 4))
|
||||
.idle_ms(50)
|
||||
.send_frame(
|
||||
frames::window_update(1, 1))
|
||||
// Receive first chunk
|
||||
.recv_frame(frames::data(1, "hello"))
|
||||
.send_frame(
|
||||
frames::window_update(1, 5))
|
||||
// Receive second chunk
|
||||
.recv_frame(
|
||||
frames::data(1, "world").eos())
|
||||
.send_frame(
|
||||
frames::headers(1)
|
||||
.response(204)
|
||||
.eos()
|
||||
)
|
||||
/*
|
||||
.recv_frame(frames::data(1, "hello").eos())
|
||||
.send_frame(frames::window_update(1, 5))
|
||||
*/
|
||||
.map(drop)
|
||||
;
|
||||
|
||||
let _ = h2.join(srv)
|
||||
.wait().unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user