Preprocess tungstenite 'ConnectionClosed' errors.

Tungstenite abuses `Err(ConnectionClosed)` to indicate the non-error
condition of a websocket closing. This commit changes error processing
such that the error is caught and converted into a successful
termination of websocket handling.
This commit is contained in:
Sergio Benitez 2023-03-30 15:24:18 -07:00
parent 64a7bfb37c
commit 1d2cc257dc
1 changed files with 16 additions and 8 deletions

View File

@ -87,14 +87,23 @@ impl<'r, 'o: 'r, S> Responder<'r, 'o> for MessageStream<'o, S>
} }
} }
/// Returns `Ok(true)` if processing should continue, `Ok(false)` if processing
/// has terminated without error, and `Err(e)` if an error has occurred.
fn handle_result(result: Result<()>) -> io::Result<bool> {
match result {
Ok(_) => Ok(true),
Err(Error::ConnectionClosed) => Ok(false),
Err(Error::Io(e)) => Err(e),
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
}
}
#[rocket::async_trait] #[rocket::async_trait]
impl IoHandler for Channel<'_> { impl IoHandler for Channel<'_> {
async fn io(&mut self, io: IoStream) -> io::Result<()> { async fn io(&mut self, io: IoStream) -> io::Result<()> {
let stream = WebSocketStream::from_raw_socket(io, Role::Server, None).await; let stream = WebSocketStream::from_raw_socket(io, Role::Server, None).await;
(self.handler)(stream).await.map_err(|e| match e { let result = (self.handler)(stream).await;
Error::Io(e) => e, handle_result(result).map(|_| ())
other => io::Error::new(io::ErrorKind::Other, other)
})
} }
} }
@ -112,10 +121,9 @@ impl<'r, S> IoHandler for MessageStream<'r, S>
Err(e) => Err(e) Err(e) => Err(e)
}; };
result.map_err(|e| match e { if !handle_result(result)? {
Error::Io(e) => e, return Ok(());
other => io::Error::new(io::ErrorKind::Other, other) }
})?;
} }
Ok(()) Ok(())