mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Give WebSocketClient the PemMemory client certificate constructor SSLClient has
Adds ws::WebSocketClient::PemMemory and a constructor overload that installs an in-memory client certificate on the TLS context, enabling mutual TLS for wss:// connections. The certificate is silently ignored for ws:// URLs, consistent with the existing TLS-only setters such as set_ca_cert_path(). Part of the interface alignment discussed in #2531.
This commit is contained in:
1 parent
bd02a50cbb
commit
86abc9a0ea
5 files changed
+155
No files matched your search
@@ -21118,6 +21118,80 @@ TEST_F(WebSocketSSLDnsHostTest, VerificationDisabledAcceptsAnyName) {
|
||||
EXPECT_EQ("hello", msg);
|
||||
client.close();
|
||||
}
|
||||
|
||||
class WebSocketSSLPemMemoryTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
server_ = httplib::detail::make_unique<SSLServer>(
|
||||
SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, CLIENT_CA_CERT_FILE);
|
||||
ASSERT_TRUE(server_->is_valid());
|
||||
server_->WebSocket("/ws-echo", [](const Request &, ws::WebSocket &ws) {
|
||||
std::string msg;
|
||||
while (ws.read(msg)) {
|
||||
ws.send(msg);
|
||||
}
|
||||
});
|
||||
port_ = server_->bind_to_any_port("localhost");
|
||||
server_thread_ = std::thread([this]() { server_->listen_after_bind(); });
|
||||
server_->wait_until_ready();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
server_->stop();
|
||||
if (server_thread_.joinable()) { server_thread_.join(); }
|
||||
}
|
||||
|
||||
std::string url() const {
|
||||
return "wss://localhost:" + std::to_string(port_) + "/ws-echo";
|
||||
}
|
||||
|
||||
void ConnectWithClientCert(const std::string &client_cert_file,
|
||||
const std::string &client_private_key_file,
|
||||
const char *private_key_password) {
|
||||
std::string cert_pem, key_pem;
|
||||
read_file(client_cert_file, cert_pem);
|
||||
read_file(client_private_key_file, key_pem);
|
||||
|
||||
ws::WebSocketClient::PemMemory pem = {cert_pem.c_str(), cert_pem.size(),
|
||||
key_pem.c_str(), key_pem.size(),
|
||||
private_key_password};
|
||||
ws::WebSocketClient client(url(), pem);
|
||||
ASSERT_TRUE(client.is_valid());
|
||||
client.enable_server_certificate_verification(false);
|
||||
|
||||
ASSERT_TRUE(client.connect());
|
||||
ASSERT_TRUE(client.send("hello"));
|
||||
std::string msg;
|
||||
EXPECT_EQ(ws::Text, client.read(msg));
|
||||
EXPECT_EQ("hello", msg);
|
||||
client.close();
|
||||
}
|
||||
|
||||
std::unique_ptr<SSLServer> server_;
|
||||
std::thread server_thread_;
|
||||
int port_ = 0;
|
||||
};
|
||||
|
||||
TEST_F(WebSocketSSLPemMemoryTest, ClientCertAccepted) {
|
||||
ConnectWithClientCert(CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE, nullptr);
|
||||
}
|
||||
|
||||
// Control for the tests above: the fixture's server really does require a
|
||||
// client certificate, so it is the PEM the constructor installed that decides
|
||||
// the outcome.
|
||||
TEST_F(WebSocketSSLPemMemoryTest, NoClientCertRejected) {
|
||||
ws::WebSocketClient client(url());
|
||||
ASSERT_TRUE(client.is_valid());
|
||||
client.enable_server_certificate_verification(false);
|
||||
|
||||
EXPECT_FALSE(client.connect());
|
||||
}
|
||||
|
||||
TEST_F(WebSocketSSLPemMemoryTest, EncryptedClientCertAccepted) {
|
||||
ConnectWithClientCert(CLIENT_ENCRYPTED_CERT_FILE,
|
||||
CLIENT_ENCRYPTED_PRIVATE_KEY_FILE,
|
||||
CLIENT_ENCRYPTED_PRIVATE_KEY_PASS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
Reference in new issue
Block a user