From b116605560591697bb15ac0b359ae7eb6cf4f4e4 Mon Sep 17 00:00:00 2001 From: Robert Ying Date: Tue, 16 Oct 2018 12:03:56 -0700 Subject: [PATCH] Check whether the send side is not idle, not the recv side (#313) * Check whether the send side is not idle, not the recv side * Ensure sure we're handling window updates for the right side * Add failing test --- src/proto/streams/streams.rs | 3 +- tests/h2-tests/tests/stream_states.rs | 55 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/proto/streams/streams.rs b/src/proto/streams/streams.rs index de59576..eb1ceaa 100644 --- a/src/proto/streams/streams.rs +++ b/src/proto/streams/streams.rs @@ -394,8 +394,7 @@ where ); } else { me.actions - .recv - .ensure_not_idle(id) + .ensure_not_idle(me.counts.peer(), id) .map_err(RecvError::Connection)?; } } diff --git a/tests/h2-tests/tests/stream_states.rs b/tests/h2-tests/tests/stream_states.rs index 3810492..b801724 100644 --- a/tests/h2-tests/tests/stream_states.rs +++ b/tests/h2-tests/tests/stream_states.rs @@ -1085,3 +1085,58 @@ fn send_err_with_buffered_data() { client.join(srv).wait().expect("wait"); } + +#[test] +fn srv_window_update_on_lower_stream_id() { + // See https://github.com/carllerche/h2/issues/208 + let _ = ::env_logger::try_init(); + let (io, srv) = mock::new(); + + let srv = srv.assert_client_handshake() + .unwrap() + .recv_settings() + .recv_frame( + frames::headers(7) + .request("GET", "https://example.com/") + .eos() + ) + .send_frame(frames::push_promise(7, 2).request("GET", "https://http2.akamai.com/style.css")) + .send_frame(frames::headers(7).eos()) + .recv_frame(frames::reset(2).cancel()) + .send_frame(frames::window_update(5, 66666)) + .close() + ; + + let client = client::Builder::new() + .initial_stream_id(7) + .handshake::<_, Bytes>(io) + .unwrap() + .and_then(|(mut client, h2)| { + let request = Request::builder() + .method("GET") + .uri("https://example.com/") + .body(()).unwrap(); + + let response = client.send_request(request, true) + .unwrap() + .0.expect("response") + .and_then(|resp| { + assert_eq!(resp.status(), StatusCode::OK); + Ok(()) + }); + + h2.expect("client") + .drive(response) + .and_then(|(h2, _)| { + println!("RESPONSE DONE"); + h2 + }) + .then(|result| { + println!("WUT"); + assert!(result.is_ok(), "result: {:?}", result); + Ok::<_, ()>(()) + }) + }); + + srv.join(client).wait().unwrap(); +}