Open pfernie opened 3 years ago
It's probably worth pointing out that this can be done already, it just isn't part of the Ws
type.
warp::ws()
.and(warp::headers::value("sec-websocket-protocol"))
.and_then(|ws, proto| {
let reply = ws.on_upgrade(something_with_websocket);
Ok(warp::reply::with_header(reply, "sec-websocket-protocol", proto))
})
Thanks, that is a straightforward solution indeed!
the headers filters moved, updated solution:
warp::ws()
.and(warp::filters::header::value("sec-websocket-protocol"))
.and_then(|ws, proto| {
let reply = ws.on_upgrade(something_with_websocket);
Ok(warp::reply::with_header(reply, "sec-websocket-protocol", proto))
})
Is there a way to allow both connections which sent with sec-websocket-protocl
but also connections which made without this header?
Because I think that warp::filters::header::value("sec-websocket-protocol")
allow only connections which has this header
let app = warp::path("ws")
// The `ws()` filter will prepare Websocket handshake...
.and(warp::ws())
.and(warp::header::optional::<String>("sec-websocket-protocol"))
.and(users)
.map(|ws: warp::ws::Ws, maybe_proto: Option<String>, users| {
// This will call our function if the handshake succeeds.
let reply = ws.on_upgrade(move |socket| user_connected(socket, users));
if let Some(proto) = maybe_proto {
return warp::reply::with_header(reply, "sec-websocket-protocol", proto)
}
return warp::reply::with_header(reply, "", "");
});
Maybe something like that, not sure. it force me to reply with header eventually
This issue is related to #496, although the use case is slightly more general.
Currently, as documented in that issue,
warp
handles theWebSocket
upgrade statically, and elides any handling of aSec-WebSocket-Protocol
header. A workaround used in #496 and similarly in async-graphql's warp integration is to manually set this header in the response to the assumed protocol (e.g.graphql-ws
).With the recent revision of the
GraphQL Over WebSockets
"spec", the situation is further complicated. The name of the protocol was changed; from the old de facto standard established by subscriptions-transport-ws the subprotocol was namedgraphql-ws
. With the revised graphql-ws, this is (confusingly) renamedgraphql-transport-ws
. But beyond wanting to reply with the same protocol as the client set in theSec-WebSocket-Protocol
header of the initialGET
request, the newgraphql-ws
protocol differs slightly from the previoussubscriptions-transport-ws
, and as such servers wanting to support both legacy and newer clients need to act (change logic) accordingly.Some solutions which would facilitate this are:
protocol
similar to the existingkey
. The headers crate does not seem to provide a typedSecWebSocketProtocol
akin toSecWebSocketKey
, so either this would beprotocol: Option<String>
, or support inheaders
could be added. Per RFC6455, it seems theSec-WebSocket-Protocol
header is optional.body
.EDIT: Per the RFC, the header may specify multiple supported protocols, so
protocol
would more appropriately beOption<Vec<String>>
, or simplyVec<String>
if there is no semantic use to distinguishing empty header from non-present header.