add SendResponse::poll_reset and SendStream::poll_reset to listen for reset streams (#279)
This commit is contained in:
@@ -926,6 +926,44 @@ fn notify_on_send_capacity() {
|
||||
done_rx.recv().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_stream_poll_reset() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let (io, srv) = mock::new();
|
||||
|
||||
let srv = srv
|
||||
.assert_client_handshake()
|
||||
.unwrap()
|
||||
.recv_settings()
|
||||
.recv_frame(
|
||||
frames::headers(1)
|
||||
.request("POST", "https://example.com/")
|
||||
)
|
||||
.send_frame(frames::reset(1).refused())
|
||||
.close();
|
||||
|
||||
let client = client::Builder::new()
|
||||
.handshake::<_, Bytes>(io)
|
||||
.expect("handshake")
|
||||
.and_then(|(mut client, conn)| {
|
||||
let request = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri("https://example.com/")
|
||||
.body(())
|
||||
.unwrap();
|
||||
|
||||
let (_response, mut tx) = client.send_request(request, false).unwrap();
|
||||
conn.drive(futures::future::poll_fn(move || {
|
||||
tx.poll_reset()
|
||||
}))
|
||||
.map(|(_, reason)| {
|
||||
assert_eq!(reason, Reason::REFUSED_STREAM);
|
||||
})
|
||||
});
|
||||
|
||||
client.join(srv).wait().expect("wait");
|
||||
}
|
||||
|
||||
const SETTINGS: &'static [u8] = &[0, 0, 0, 4, 0, 0, 0, 0, 0];
|
||||
const SETTINGS_ACK: &'static [u8] = &[0, 0, 0, 4, 1, 0, 0, 0, 0];
|
||||
|
||||
|
||||
@@ -449,3 +449,143 @@ fn too_big_headers_sends_reset_after_431_if_not_eos() {
|
||||
|
||||
srv.join(client).wait().expect("wait");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poll_reset() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let (io, client) = mock::new();
|
||||
|
||||
let client = client
|
||||
.assert_server_handshake()
|
||||
.unwrap()
|
||||
.recv_settings()
|
||||
.send_frame(
|
||||
frames::headers(1)
|
||||
.request("GET", "https://example.com/")
|
||||
.eos()
|
||||
)
|
||||
.idle_ms(10)
|
||||
.send_frame(frames::reset(1).cancel())
|
||||
.close();
|
||||
|
||||
let srv = server::Builder::new()
|
||||
.handshake::<_, Bytes>(io)
|
||||
.expect("handshake")
|
||||
.and_then(|srv| {
|
||||
srv.into_future()
|
||||
.expect("server")
|
||||
.map(|(req, conn)| {
|
||||
(req.expect("request"), conn)
|
||||
})
|
||||
})
|
||||
.and_then(|((_req, mut tx), conn)| {
|
||||
let conn = conn.into_future()
|
||||
.map(|(req, _)| assert!(req.is_none(), "no second request"))
|
||||
.expect("conn");
|
||||
conn.join(
|
||||
futures::future::poll_fn(move || {
|
||||
tx.poll_reset()
|
||||
})
|
||||
.map(|reason| {
|
||||
assert_eq!(reason, Reason::CANCEL);
|
||||
})
|
||||
.expect("poll_reset")
|
||||
)
|
||||
});
|
||||
|
||||
srv.join(client).wait().expect("wait");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poll_reset_io_error() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let (io, client) = mock::new();
|
||||
|
||||
let client = client
|
||||
.assert_server_handshake()
|
||||
.unwrap()
|
||||
.recv_settings()
|
||||
.send_frame(
|
||||
frames::headers(1)
|
||||
.request("GET", "https://example.com/")
|
||||
.eos()
|
||||
)
|
||||
.idle_ms(10)
|
||||
.close();
|
||||
|
||||
let srv = server::Builder::new()
|
||||
.handshake::<_, Bytes>(io)
|
||||
.expect("handshake")
|
||||
.and_then(|srv| {
|
||||
srv.into_future()
|
||||
.expect("server")
|
||||
.map(|(req, conn)| {
|
||||
(req.expect("request"), conn)
|
||||
})
|
||||
})
|
||||
.and_then(|((_req, mut tx), conn)| {
|
||||
let conn = conn.into_future()
|
||||
.map(|(req, _)| assert!(req.is_none(), "no second request"))
|
||||
.expect("conn");
|
||||
conn.join(
|
||||
futures::future::poll_fn(move || {
|
||||
tx.poll_reset()
|
||||
})
|
||||
.expect_err("poll_reset should error")
|
||||
)
|
||||
});
|
||||
|
||||
srv.join(client).wait().expect("wait");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poll_reset_after_send_response_is_user_error() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let (io, client) = mock::new();
|
||||
|
||||
let client = client
|
||||
.assert_server_handshake()
|
||||
.unwrap()
|
||||
.recv_settings()
|
||||
.send_frame(
|
||||
frames::headers(1)
|
||||
.request("GET", "https://example.com/")
|
||||
.eos()
|
||||
)
|
||||
.recv_frame(
|
||||
frames::headers(1)
|
||||
.response(200)
|
||||
)
|
||||
.recv_frame(
|
||||
// After the error, our server will drop the handles,
|
||||
// meaning we receive a RST_STREAM here.
|
||||
frames::reset(1).cancel()
|
||||
)
|
||||
.idle_ms(10)
|
||||
.close();
|
||||
|
||||
let srv = server::Builder::new()
|
||||
.handshake::<_, Bytes>(io)
|
||||
.expect("handshake")
|
||||
.and_then(|srv| {
|
||||
srv.into_future()
|
||||
.expect("server")
|
||||
.map(|(req, conn)| {
|
||||
(req.expect("request"), conn)
|
||||
})
|
||||
})
|
||||
.and_then(|((_req, mut tx), conn)| {
|
||||
let conn = conn.into_future()
|
||||
.map(|(req, _)| assert!(req.is_none(), "no second request"))
|
||||
.expect("conn");
|
||||
tx.send_response(Response::new(()), false).expect("response");
|
||||
conn.join(
|
||||
futures::future::poll_fn(move || {
|
||||
tx.poll_reset()
|
||||
})
|
||||
.expect_err("poll_reset should error")
|
||||
)
|
||||
});
|
||||
|
||||
srv.join(client).wait().expect("wait");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user