From 6f3e861e2745714fbf6e3bcedbd88ebc73a480c8 Mon Sep 17 00:00:00 2001 From: Patrick Fernie Date: Fri, 4 Dec 2020 12:16:14 -0500 Subject: [PATCH] support client specifying multiple protocols in Sec-WebSocket-Protocol negotiation --- integrations/actix-web/src/subscription.rs | 7 +++++-- integrations/warp/src/subscription.rs | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/integrations/actix-web/src/subscription.rs b/integrations/actix-web/src/subscription.rs index 0d3fe3fc..be123bd1 100644 --- a/integrations/actix-web/src/subscription.rs +++ b/integrations/actix-web/src/subscription.rs @@ -60,8 +60,11 @@ where .headers() .get("sec-websocket-protocol") .and_then(|value| value.to_str().ok()) - .and_then(|value| WebSocketProtocols::from_str(value).ok()) - { + .and_then(|protocols| { + protocols + .split(',') + .find_map(|p| WebSocketProtocols::from_str(p.trim()).ok()) + }) { Some(protocol) => protocol, None => { // default to the prior standard diff --git a/integrations/warp/src/subscription.rs b/integrations/warp/src/subscription.rs index 171d7aea..6f56d1a3 100644 --- a/integrations/warp/src/subscription.rs +++ b/integrations/warp/src/subscription.rs @@ -65,22 +65,21 @@ where F: FnOnce(serde_json::Value) -> Result + Send + Sync + Clone + 'static, { use async_graphql::http::WebSocketProtocols; + use std::str::FromStr; warp::ws() - .and(warp::header::optional::( - "sec-websocket-protocol", - )) - .map(move |ws: ws::Ws, protocol| { + .and(warp::header::optional::("sec-websocket-protocol")) + .map(move |ws: ws::Ws, protocols: Option| { let schema = schema.clone(); let initializer = initializer.clone(); - let protocol = match protocol { - Some(protocol) => protocol, - None => { - // default to the prior standard - WebSocketProtocols::SubscriptionsTransportWS - } - }; + let protocol = protocols + .and_then(|protocols| { + protocols + .split(',') + .find_map(|p| WebSocketProtocols::from_str(p.trim()).ok()) + }) + .unwrap_or(WebSocketProtocols::SubscriptionsTransportWS); let reply = ws.on_upgrade(move |websocket| { let (ws_sender, ws_receiver) = websocket.split();