mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-27 12:31:28 +00:00
Ignore a subprotocol the WebSocket client did not offer
A SubProtocolSelector could return a value outside the client's Sec-WebSocket-Protocol list, and the server sent it back as is. The server now treats such a value as no selection.
This commit is contained in:
1 parent
4fcbc08f2d
commit
6d1049462d
3 files changed
+31
-1
No files matched your search
+1
-1
@@ -119,7 +119,7 @@ using SubProtocolSelector =
|
|||||||
std::function<std::string(const std::vector<std::string> &protocols)>;
|
std::function<std::string(const std::vector<std::string> &protocols)>;
|
||||||
```
|
```
|
||||||
|
|
||||||
The `SubProtocolSelector` receives the list of subprotocols proposed by the client (from the `Sec-WebSocket-Protocol` header) and returns the selected one. Return an empty string to decline all proposed subprotocols.
|
The `SubProtocolSelector` receives the list of subprotocols proposed by the client (from the `Sec-WebSocket-Protocol` header) and returns the selected one. Return an empty string to decline all proposed subprotocols. A returned value that the client did not propose is ignored.
|
||||||
|
|
||||||
### WebSocket (Server-side)
|
### WebSocket (Server-side)
|
||||||
|
|
||||||
|
|||||||
@@ -14692,6 +14692,12 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
|
|||||||
protocols.emplace_back(b, e);
|
protocols.emplace_back(b, e);
|
||||||
});
|
});
|
||||||
selected_subprotocol = entry.sub_protocol_selector(protocols);
|
selected_subprotocol = entry.sub_protocol_selector(protocols);
|
||||||
|
|
||||||
|
// Ignore a selection the client did not offer (RFC 6455 4.2.2)
|
||||||
|
if (std::find(protocols.begin(), protocols.end(),
|
||||||
|
selected_subprotocol) == protocols.end()) {
|
||||||
|
selected_subprotocol.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24061,6 +24061,18 @@ protected:
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server_->WebSocket(
|
||||||
|
"/ws-subprotocol-unoffered",
|
||||||
|
[](const Request &, ws::WebSocket &ws) {
|
||||||
|
std::string msg;
|
||||||
|
while (ws.read(msg)) {
|
||||||
|
ws.send(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[](const std::vector<std::string> &) -> std::string {
|
||||||
|
return "admin";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_server() {
|
void start_server() {
|
||||||
@@ -24403,6 +24415,18 @@ TEST_F(WebSocketIntegrationTest, SubProtocolNoMatch) {
|
|||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WebSocketIntegrationTest, SubProtocolSelectorReturnsUnoffered) {
|
||||||
|
Headers headers = {{"Sec-WebSocket-Protocol", "chat"}};
|
||||||
|
ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) +
|
||||||
|
"/ws-subprotocol-unoffered",
|
||||||
|
headers);
|
||||||
|
ASSERT_TRUE(client.connect());
|
||||||
|
|
||||||
|
EXPECT_TRUE(client.subprotocol().empty());
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WebSocketIntegrationTest, SubProtocolNotRequested) {
|
TEST_F(WebSocketIntegrationTest, SubProtocolNotRequested) {
|
||||||
// Connect without requesting any subprotocol
|
// Connect without requesting any subprotocol
|
||||||
ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) +
|
ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) +
|
||||||
|
|||||||
Reference in new issue
Block a user