#![cfg(feature = "ws")]
#[cfg(feature = "__rt_native__")]
mod native;
#[cfg(feature = "__rt_native__")]
pub use self::native::*;
#[cfg(feature = "rt_worker")]
mod worker;
#[cfg(feature = "rt_worker")]
pub use self::worker::*;
pub struct WebSocketContext<'req> {
#[allow(unused/* on rt_worker */)]
sec_websocket_key: &'req str,
}
impl<'req> crate::FromRequest<'req> for WebSocketContext<'req> {
type Error = crate::Response;
#[inline]
fn from_request(req: &'req crate::Request) -> Option<Result<Self, Self::Error>> {
#[cold]
#[inline(never)]
fn reject(message: &'static str) -> crate::Response {
crate::Response::BadRequest().with_text(message)
}
if !matches!(req.headers.connection()?, "Upgrade" | "upgrade") {
return Some(Err(reject(
"upgrade request must have `Connection: Upgrade`",
)));
}
if !(req.headers.upgrade()?.eq_ignore_ascii_case("websocket")) {
return Some(Err(reject(
"upgrade request must have `Upgrade: websocket`",
)));
}
if req.headers.sec_websocket_version()? != "13" {
return Some(Err(reject(
"upgrade request must have `Sec-WebSocket-Version: 13`",
)));
}
req.headers
.sec_websocket_key()
.map(|sec_websocket_key| Ok(Self { sec_websocket_key }))
}
}
impl<'req> WebSocketContext<'req> {
pub fn new(sec_websocket_key: &'req str) -> Self {
Self { sec_websocket_key }
}
}