mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-29 00:00:18 +02:00
Return rejection if WebSocket request couldn't be upgraded (#1135)
* Return rejection if `WebSocket` request couldn't be upgraded * make rejection about connection upgrades * changelog links
This commit is contained in:
+6
-1
@@ -7,7 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- None.
|
- **fixed:** If `WebSocketUpgrade` cannot upgrade the connection it will return a
|
||||||
|
`WebSocketUpgradeRejection::ConnectionNotUpgradable` rejection ([#1135])
|
||||||
|
- **changed:** `WebSocketUpgradeRejection` has a new variant `ConnectionNotUpgradable`
|
||||||
|
variant ([#1135])
|
||||||
|
|
||||||
|
[#1135]: https://github.com/tokio-rs/axum/pull/1135
|
||||||
|
|
||||||
# 0.5.12 (10. July, 2022)
|
# 0.5.12 (10. July, 2022)
|
||||||
|
|
||||||
|
|||||||
+57
-7
@@ -267,14 +267,15 @@ where
|
|||||||
return Err(InvalidWebSocketVersionHeader.into());
|
return Err(InvalidWebSocketVersionHeader.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let sec_websocket_key =
|
let sec_websocket_key = req
|
||||||
if let Some(key) = req.headers_mut().remove(header::SEC_WEBSOCKET_KEY) {
|
.headers_mut()
|
||||||
key
|
.remove(header::SEC_WEBSOCKET_KEY)
|
||||||
} else {
|
.ok_or(WebSocketKeyHeaderMissing)?;
|
||||||
return Err(WebSocketKeyHeaderMissing.into());
|
|
||||||
};
|
|
||||||
|
|
||||||
let on_upgrade = req.extensions_mut().remove::<OnUpgrade>().unwrap();
|
let on_upgrade = req
|
||||||
|
.extensions_mut()
|
||||||
|
.remove::<OnUpgrade>()
|
||||||
|
.ok_or(ConnectionNotUpgradable)?;
|
||||||
|
|
||||||
let sec_websocket_protocol = req.headers().get(header::SEC_WEBSOCKET_PROTOCOL).cloned();
|
let sec_websocket_protocol = req.headers().get(header::SEC_WEBSOCKET_PROTOCOL).cloned();
|
||||||
|
|
||||||
@@ -564,6 +565,20 @@ pub mod rejection {
|
|||||||
pub struct WebSocketKeyHeaderMissing;
|
pub struct WebSocketKeyHeaderMissing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define_rejection! {
|
||||||
|
#[status = UPGRADE_REQUIRED]
|
||||||
|
#[body = "WebSocket request couldn't be upgraded since no upgrade state was present"]
|
||||||
|
/// Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
||||||
|
///
|
||||||
|
/// This rejection is returned if the connection cannot be upgraded for example if the
|
||||||
|
/// request is HTTP/1.0.
|
||||||
|
///
|
||||||
|
/// See [MDN] for more details about connection upgrades.
|
||||||
|
///
|
||||||
|
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
|
||||||
|
pub struct ConnectionNotUpgradable;
|
||||||
|
}
|
||||||
|
|
||||||
composite_rejection! {
|
composite_rejection! {
|
||||||
/// Rejection used for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
/// Rejection used for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
||||||
///
|
///
|
||||||
@@ -575,6 +590,7 @@ pub mod rejection {
|
|||||||
InvalidUpgradeHeader,
|
InvalidUpgradeHeader,
|
||||||
InvalidWebSocketVersionHeader,
|
InvalidWebSocketVersionHeader,
|
||||||
WebSocketKeyHeaderMissing,
|
WebSocketKeyHeaderMissing,
|
||||||
|
ConnectionNotUpgradable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -640,3 +656,37 @@ pub mod close_code {
|
|||||||
/// action.
|
/// action.
|
||||||
pub const AGAIN: u16 = 1013;
|
pub const AGAIN: u16 = 1013;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::{body::Body, routing::get};
|
||||||
|
use http::{Request, Version};
|
||||||
|
use tower::ServiceExt;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn rejects_http_1_0_requests() {
|
||||||
|
let svc = get(|ws: Result<WebSocketUpgrade, WebSocketUpgradeRejection>| {
|
||||||
|
let rejection = ws.unwrap_err();
|
||||||
|
assert!(matches!(
|
||||||
|
rejection,
|
||||||
|
WebSocketUpgradeRejection::ConnectionNotUpgradable(_)
|
||||||
|
));
|
||||||
|
std::future::ready(())
|
||||||
|
});
|
||||||
|
|
||||||
|
let req = Request::builder()
|
||||||
|
.version(Version::HTTP_10)
|
||||||
|
.method(Method::GET)
|
||||||
|
.header("upgrade", "websocket")
|
||||||
|
.header("connection", "Upgrade")
|
||||||
|
.header("sec-websocket-key", "6D69KGBOr4Re+Nj6zx9aQA==")
|
||||||
|
.header("sec-websocket-version", "13")
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let res = svc.oneshot(req).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(res.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user