diff --git a/Cargo.toml b/Cargo.toml index de03638..0ad6b91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ slab = "0.4.0" string = { git = "https://github.com/carllerche/string" } [dev-dependencies] -mock-io = { git = "https://github.com/carllerche/mock-io" } +mock-io = { git = "https://github.com/carllerche/mock-io", branch = "experiments" } # Fuzzing quickcheck = "0.4.1" diff --git a/src/proto/settings.rs b/src/proto/settings.rs index 31ee017..69683fd 100644 --- a/src/proto/settings.rs +++ b/src/proto/settings.rs @@ -38,9 +38,12 @@ impl Settings { let frame = frame::Settings::ack(); if let AsyncSink::NotReady(_) = dst.start_send(frame.into())? { + trace!("failed to send ACK"); return Ok(Async::NotReady); } + trace!("ACK sent"); + dst.apply_remote_settings(settings); streams.apply_remote_settings(settings); } diff --git a/tests/prioritization.rs b/tests/prioritization.rs index 070903e..b561bf5 100644 --- a/tests/prioritization.rs +++ b/tests/prioritization.rs @@ -45,7 +45,7 @@ fn single_stream_send_large_body() { } #[test] -fn single_stream_send_extra_large_body_multi_frames() { +fn single_stream_send_extra_large_body_multi_frames_one_buffer() { let _ = ::env_logger::init(); let payload = vec![0; 32_768]; @@ -91,3 +91,64 @@ fn single_stream_send_extra_large_body_multi_frames() { h2.wait().unwrap(); } + +#[test] +fn single_stream_send_extra_large_body_multi_frames_multi_buffer() { + let _ = ::env_logger::init(); + + let payload = vec![0; 32_768]; + + let mock = mock_io::Builder::new() + // .handshake() + .write(b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n") + .write(frames::SETTINGS) + .read(frames::SETTINGS) + // Add wait to force the data writes to chill + .wait(Duration::from_millis(10)) + + // Rest + + .write(&[ + // POST / + 0, 0, 16, 1, 4, 0, 0, 0, 1, 131, 135, 65, 139, 157, 41, + 172, 75, 143, 168, 233, 25, 151, 33, 233, 132, + ]) + .write(&[ + // DATA + 0, 64, 0, 0, 0, 0, 0, 0, 1, + ]) + .write(&payload[0..16_384]) + + .write(frames::SETTINGS_ACK) + .read(frames::SETTINGS_ACK) + .wait(Duration::from_millis(10)) + + .write(&[ + // DATA + 0, 64, 0, 0, 1, 0, 0, 0, 1, + ]) + .write(&payload[16_384..]) + // Read response + .read(&[0, 0, 1, 1, 5, 0, 0, 0, 1, 0x89]) + .build(); + + let mut h2 = Client::handshake(mock) + .wait().unwrap(); + + let request = Request::builder() + .method(method::POST) + .uri("https://http2.akamai.com/") + .body(()).unwrap(); + + let mut stream = h2.request(request, false).unwrap(); + + // Send the data + stream.send_data(payload.into(), true).unwrap(); + + // Get the response + let resp = h2.run(poll_fn(|| stream.poll_response())).unwrap(); + + assert_eq!(resp.status(), status::NO_CONTENT); + + h2.wait().unwrap(); +} diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 47869d8..8f58b44 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -35,6 +35,8 @@ pub use self::bytes::{ IntoBuf, }; +pub use std::time::Duration; + use tokio_io::{AsyncRead, AsyncWrite}; pub trait MockH2 {