Skip to content

Commit ead0e12

Browse files
author
Kasper Peeters
committed
Fix websocket_client bug connecting to servers requiring SNI. Fix patterns chapter in docs.
1 parent 62daf9c commit ead0e12

File tree

3 files changed

+494
-410
lines changed

3 files changed

+494
-410
lines changed

client_server/websocket_client.cc

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,36 @@
22
#include <iostream>
33

44
websocket_client::websocket_client()
5-
: ssl_ctx_(boost::asio::ssl::context::tlsv12_client)
5+
: ssl_ctx_(boost::asio::ssl::context::sslv23_client) // tlsv12_client)
66
, resolver_(ioc_)
77
, is_ssl_(false)
88
{
99
ssl_ctx_.set_default_verify_paths();
10+
#ifdef __APPLE__
11+
#include <TargetConditionals.h>
12+
#if TARGET_OS_IPHONE
13+
ssl_ctx_.set_verify_mode(boost::asio::ssl::verify_none);
14+
#else
15+
// on MacOS or related, include the system certificate chain.
16+
ssl_ctx_.set_verify_mode(boost::asio::ssl::verify_none);
17+
// ssl_ctx_.load_verify_file("/etc/ssl/cert.pem");
18+
// ssl_ctx_.set_verify_mode(boost::asio::ssl::verify_peer);
19+
// Configure SSL context to be more permissive
20+
#endif
21+
// ssl_ctx_.set_options(boost::asio::ssl::context::default_workarounds |
22+
// boost::asio::ssl::context::no_sslv2 |
23+
// boost::asio::ssl::context::no_sslv3);
24+
#else
1025
ssl_ctx_.set_verify_mode(boost::asio::ssl::verify_peer);
26+
#endif
27+
// ssl_ctx_.set_verify_callback([](bool preverified, ssl::verify_context& ctx) {
28+
// // Log verification details for debugging
29+
// char subject_name[256];
30+
// X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
31+
// X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
32+
// std::cerr << "websocket_client::verify_callback: " << subject_name << "\n";
33+
// return preverified;
34+
// });
1135
}
1236

1337
websocket_client::~websocket_client()
@@ -49,6 +73,23 @@ void websocket_client::connect(const std::string& uri_string)
4973
wss_stream_->binary(false); // Set to text mode
5074
wss_stream_->auto_fragment(false); // Don't fragment messages
5175
wss_stream_->read_message_max(64 * 1024 * 1024); // 64MB max message size
76+
// ssl_ctx_.set_verify_callback(
77+
// [host](bool preverified, ssl::verify_context& ctx) {
78+
// // You can add debug logging here to see verification attempts
79+
// std::cerr << "Verifying certificate: " << preverified << std::endl;
80+
// return preverified;
81+
// });
82+
// wss_stream_->next_layer().set_server_hostname(host_);
83+
wss_stream_->set_option(boost::beast::websocket::stream_base::decorator(
84+
[](boost::beast::websocket::request_type& req) {
85+
req.version(11);
86+
req.set(boost::beast::http::field::user_agent, "WebSocket-Client/1.0");
87+
// Log all headers
88+
// for (auto const& field : req) {
89+
// std::cerr << field.name_string() << ": "
90+
// << field.value() << "\n";
91+
// }
92+
}));
5293
}
5394
else {
5495
ws_stream_ = std::make_unique<boost::beast::websocket::stream<
@@ -96,6 +137,14 @@ void websocket_client::on_connect(const boost::beast::error_code& ec)
96137
if (ec) return fail(ec);
97138

98139
if (is_ssl_) {
140+
if (!SSL_set_tlsext_host_name(
141+
wss_stream_->next_layer().native_handle(), host_.c_str())) {
142+
throw boost::beast::system_error{
143+
boost::beast::error_code{
144+
static_cast<int>(::ERR_get_error()),
145+
boost::beast::net::error::get_ssl_category()}};
146+
}
147+
99148
wss_stream_->next_layer().async_handshake(
100149
boost::asio::ssl::stream_base::client,
101150
[this](const boost::beast::error_code& ec) {

0 commit comments

Comments
 (0)