mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-09 03:51:42 +00:00
fix(collab-net): give a management request one deadline for its answer
reply read until the server answered, and every ping, pong or control frame renewed the per-read timeout, so a library endpoint could hold a background refresh (and the shared refresh permit) open indefinitely. The whole exchange now ends at one absolute deadline, the idle timeout from when the request went out.
This commit is contained in:
1 parent
02c38a6d95
commit
31a60ed360
1 file changed
+8
@@ -206,7 +206,15 @@ fn send(ws: &mut Ws, msg: &ClientMsg) -> Result<(), String> {
|
||||
|
||||
/// The next answer `pick` takes, or why there is none.
|
||||
fn reply<T>(ws: &mut Ws, limits: &NetLimits, pick: impl Fn(ServerMsg) -> Option<T>) -> Result<T, String> {
|
||||
// One deadline for the whole answer: pings, pongs and a message trickling in each renew the
|
||||
// read timeout, so without it a server could keep a request (and the refresh permit the
|
||||
// caller holds) waiting for as long as it liked.
|
||||
let until = std::time::Instant::now() + limits.idle_timeout;
|
||||
ws.get_mut().read_until(Some(until));
|
||||
loop {
|
||||
if std::time::Instant::now() >= until {
|
||||
return Err("no answer from the server (it took too long)".into());
|
||||
}
|
||||
return match ws.read() {
|
||||
Ok(Message::Binary(b)) => match message::decode::<ServerMsg>(&b, limits.max_server_message) {
|
||||
Ok(ServerMsg::Refused { reason }) => Err(format!("{REFUSED}{reason}")),
|
||||
|
||||
Reference in new issue
Block a user