Skip to content

Commit d761de9

Browse files
authored
Merge pull request #21 from nabto/sc3933
Sc3933
2 parents e017e85 + 7765db4 commit d761de9

File tree

7 files changed

+116
-25
lines changed

7 files changed

+116
-25
lines changed

examples/libdatachannel/src/common/libdatachannel_websocket/rtc_websocket_wrapper.hpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <nabto/webrtc/device.hpp>
44
#include <nabto/webrtc/util/logging.hpp>
5+
#include <optional>
56
#include <rtc/rtc.hpp>
67
#include <variant>
78

@@ -12,21 +13,30 @@ class RtcWebsocketWrapper
1213
: public nabto::webrtc::SignalingWebsocket,
1314
public std::enable_shared_from_this<RtcWebsocketWrapper> {
1415
public:
15-
static nabto::webrtc::SignalingWebsocketPtr create() {
16-
return std::make_shared<RtcWebsocketWrapper>();
16+
static nabto::webrtc::SignalingWebsocketPtr create(
17+
std::optional<std::string> caBundle) {
18+
return std::make_shared<RtcWebsocketWrapper>(caBundle);
1719
}
1820

19-
RtcWebsocketWrapper() {}
21+
RtcWebsocketWrapper(std::optional<std::string>& caBundle) {
22+
if (caBundle.has_value()) {
23+
rtc::WebSocketConfiguration conf;
24+
conf.caCertificatePemFile = caBundle;
25+
ws_ = std::make_shared<rtc::WebSocket>(conf);
26+
} else {
27+
ws_ = std::make_shared<rtc::WebSocket>();
28+
}
29+
}
2030

21-
bool send(const std::string& data) { return ws_.send(data); }
31+
bool send(const std::string& data) { return ws_->send(data); }
2232

23-
void close() { return ws_.close(); }
33+
void close() { return ws_->close(); }
2434

25-
void onOpen(std::function<void()> callback) { ws_.onOpen(callback); }
35+
void onOpen(std::function<void()> callback) { ws_->onOpen(callback); }
2636

2737
void onMessage(std::function<void(const std::string& message)> callback) {
2838
auto self = shared_from_this();
29-
ws_.onMessage(
39+
ws_->onMessage(
3040
[self, callback](std::variant<rtc::binary, rtc::string> message) {
3141
std::string msg;
3242
if (std::holds_alternative<rtc::string>(message)) {
@@ -42,16 +52,16 @@ class RtcWebsocketWrapper
4252
});
4353
}
4454

45-
void onClosed(std::function<void()> callback) { ws_.onClosed(callback); }
55+
void onClosed(std::function<void()> callback) { ws_->onClosed(callback); }
4656

47-
void open(const std::string& url) { ws_.open(url); }
57+
void open(const std::string& url) { ws_->open(url); }
4858

4959
void onError(std::function<void(const std::string& error)> callback) {
50-
ws_.onError(callback);
60+
ws_->onError(callback);
5161
}
5262

5363
private:
54-
rtc::WebSocket ws_;
64+
std::shared_ptr<rtc::WebSocket> ws_;
5565
};
5666

5767
} // namespace example

examples/libdatachannel/src/webrtc_device/main.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <nabto/webrtc/util/message_transport.hpp>
1212
#include <nabto/webrtc/util/std_timer.hpp>
1313
#include <nabto/webrtc/util/token_generator.hpp>
14+
#include <optional>
1415
#include <webrtc_connection/webrtc_connection.hpp>
1516

1617
#include "h264_handler.hpp"
@@ -24,6 +25,7 @@ struct options {
2425
std::string sharedSecret;
2526
std::string sharedSecretId;
2627
bool centralAuthorization;
28+
std::optional<std::string> caBundle;
2729
};
2830

2931
bool parse_options(int argc, char** argv, struct options& opts);
@@ -50,8 +52,8 @@ int main(int argc, char** argv) {
5052
nabto::webrtc::util::NabtoTokenGenerator::create(
5153
opts.productId, opts.deviceId, opts.privateKey);
5254

53-
auto http = nabto::webrtc::util::CurlHttpClient::create();
54-
auto ws = nabto::example::RtcWebsocketWrapper::create();
55+
auto http = nabto::webrtc::util::CurlHttpClient::create(opts.caBundle);
56+
auto ws = nabto::example::RtcWebsocketWrapper::create(opts.caBundle);
5557
auto tf = nabto::webrtc::util::StdTimerFactory::create();
5658
auto trackHandler = nabto::example::H264TrackHandler::create(nullptr);
5759

@@ -122,14 +124,24 @@ bool parse_options(int argc, char** argv, struct options& opts) {
122124
"Optional. Shared secret used to sign and validate signaling messages",
123125
cxxopts::value<std::string>())("central-authorization",
124126
"Require central authorization")(
125-
"h,help", "Shows this help text");
127+
"ca-bundle",
128+
"Optional. Path to a CA certificate file; overrides CURL_CA_BUNDLE "
129+
"env var if set.",
130+
cxxopts::value<std::string>())("h,help", "Shows this help text")(
131+
"v,version", "Shows the Nabto WebRTC SDK version");
126132
auto result = options.parse(argc, argv);
127133

128134
if (result.count("help")) {
129135
std::cout << options.help({"", "Group"}) << std::endl;
130136
return false;
131137
}
132138

139+
if (result.count("version")) {
140+
std::cout << "Nabto WebRTC SDK C++: "
141+
<< nabto::webrtc::SignalingDevice::version() << std::endl;
142+
return false;
143+
}
144+
133145
if (result.count("deviceid") && result.count("productid")) {
134146
opts.deviceId = result["deviceid"].as<std::string>();
135147
opts.productId = result["productid"].as<std::string>();
@@ -176,6 +188,23 @@ bool parse_options(int argc, char** argv, struct options& opts) {
176188
return false;
177189
}
178190

191+
if (result.count("ca-bundle")) {
192+
opts.caBundle = result["ca-bundle"].as<std::string>();
193+
} else {
194+
const char* curlCaBundle = std::getenv("CURL_CA_BUNDLE");
195+
if (curlCaBundle != nullptr) {
196+
opts.caBundle = std::string(curlCaBundle);
197+
}
198+
}
199+
if (opts.caBundle.has_value()) {
200+
std::ifstream f(opts.caBundle.value());
201+
if (!f.good()) {
202+
std::cout << "CA certificate bundle file does not exist: "
203+
<< opts.caBundle.value() << std::endl;
204+
return false;
205+
}
206+
}
207+
179208
} catch (const cxxopts::exceptions::exception& e) {
180209
std::cout << "Error parsing options: " << e.what() << std::endl;
181210
return false;

examples/libdatachannel/src/webrtc_device_rtsp/main.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <nabto/webrtc/util/message_transport.hpp>
1212
#include <nabto/webrtc/util/std_timer.hpp>
1313
#include <nabto/webrtc/util/token_generator.hpp>
14+
#include <optional>
1415
#include <webrtc_connection/webrtc_connection.hpp>
1516

1617
#include "h264_opus_rtsp_handler.hpp"
@@ -25,6 +26,7 @@ struct options {
2526
std::string sharedSecretId;
2627
bool centralAuthorization;
2728
std::string rtspUrl;
29+
std::optional<std::string> caBundle;
2830
};
2931

3032
bool parse_options(int argc, char** argv, struct options& opts);
@@ -50,8 +52,10 @@ int main(int argc, char** argv) {
5052
nabto::webrtc::util::NabtoTokenGenerator::create(
5153
opts.productId, opts.deviceId, opts.privateKey);
5254

53-
auto http = nabto::webrtc::util::CurlHttpClient::create();
54-
auto ws = nabto::example::RtcWebsocketWrapper::create();
55+
nabto::webrtc::SignalingHttpClientPtr http =
56+
nabto::webrtc::util::CurlHttpClient::create(opts.caBundle);
57+
nabto::webrtc::SignalingWebsocketPtr ws =
58+
nabto::example::RtcWebsocketWrapper::create(opts.caBundle);
5559
auto tf = nabto::webrtc::util::StdTimerFactory::create();
5660
auto trackHandler = nabto::example::H264TrackHandler::create(opts.rtspUrl);
5761

@@ -125,14 +129,24 @@ bool parse_options(int argc, char** argv, struct options& opts) {
125129
cxxopts::value<std::string>())("central-authorization",
126130
"Require central authorization")(
127131
"r,rtsp-url", "URL for the RTSP server", cxxopts::value<std::string>())(
128-
"h,help", "Shows this help text");
132+
"ca-bundle",
133+
"Optional. Path to a CA certificate file; overrides CURL_CA_BUNDLE "
134+
"env var if set.",
135+
cxxopts::value<std::string>())("h,help", "Shows this help text")(
136+
"v,version", "Shows the Nabto WebRTC SDK version");
129137
auto result = options.parse(argc, argv);
130138

131139
if (result.count("help")) {
132140
std::cout << options.help({"", "Group"}) << std::endl;
133141
return false;
134142
}
135143

144+
if (result.count("version")) {
145+
std::cout << "Nabto WebRTC SDK C++: "
146+
<< nabto::webrtc::SignalingDevice::version() << std::endl;
147+
return false;
148+
}
149+
136150
if (result.count("deviceid") && result.count("productid")) {
137151
opts.deviceId = result["deviceid"].as<std::string>();
138152
opts.productId = result["productid"].as<std::string>();
@@ -187,6 +201,23 @@ bool parse_options(int argc, char** argv, struct options& opts) {
187201
return false;
188202
}
189203

204+
if (result.count("ca-bundle")) {
205+
opts.caBundle = result["ca-bundle"].as<std::string>();
206+
} else {
207+
const char* curlCaBundle = std::getenv("CURL_CA_BUNDLE");
208+
if (curlCaBundle != nullptr) {
209+
opts.caBundle = std::string(curlCaBundle);
210+
}
211+
}
212+
if (opts.caBundle.has_value()) {
213+
std::ifstream f(opts.caBundle.value());
214+
if (!f.good()) {
215+
std::cout << "CA certificate bundle file does not exist: "
216+
<< opts.caBundle.value() << std::endl;
217+
return false;
218+
}
219+
}
220+
190221
} catch (const cxxopts::exceptions::exception& e) {
191222
std::cout << "Error parsing options: " << e.what() << std::endl;
192223
return false;

sdk/integration_test/test_instance.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class TestInstance : public std::enable_shared_from_this<TestInstance> {
100100
}
101101

102102
nabto::webrtc::SignalingDevicePtr createDevice() {
103-
http_ = nabto::webrtc::util::CurlHttpClient::create();
103+
http_ = nabto::webrtc::util::CurlHttpClient::create(std::nullopt);
104104
ws_ = nabto::example::RtcWebsocketWrapper::create();
105105
tf_ = nabto::webrtc::util::StdTimerFactory::create();
106106
tokGen_ = TestTokenGen::create(accessToken_);

sdk/src/signaling_util/curl_http_client/include/nabto/webrtc/util/curl_async.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <functional>
88
#include <memory>
99
#include <mutex>
10+
#include <optional>
1011
#include <thread>
1112

1213
namespace nabto {
@@ -24,13 +25,15 @@ class CurlHttpClient : public nabto::webrtc::SignalingHttpClient,
2425
public std::enable_shared_from_this<CurlHttpClient> {
2526
public:
2627
/**
27-
* Create an instance of the SignalingHttpClient.
28+
* Create an instance of the SignalingHttpClient with a custom CA bundle.
2829
*
30+
* @param caBundle path to the CA bundle to use
2931
* @return Smart pointer to the created SignalingHttpClient.
3032
*/
31-
static nabto::webrtc::SignalingHttpClientPtr create();
33+
static nabto::webrtc::SignalingHttpClientPtr create(
34+
std::optional<std::string> caBundle);
3235

33-
CurlHttpClient();
36+
explicit CurlHttpClient(std::optional<std::string>& caBundle);
3437
~CurlHttpClient() override;
3538
CurlHttpClient(const CurlHttpClient&) = delete;
3639
CurlHttpClient& operator=(const CurlHttpClient&) = delete;
@@ -46,6 +49,7 @@ class CurlHttpClient : public nabto::webrtc::SignalingHttpClient,
4649
std::string writeBuffer_;
4750
std::string authHeader_;
4851
std::string ctHeader_;
52+
std::optional<std::string> caBundle_;
4953

5054
struct curl_slist* curlReqHeaders_ = nullptr;
5155

sdk/src/signaling_util/curl_http_client/src/curl_async.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,21 @@
1212
#include <functional>
1313
#include <memory>
1414
#include <mutex>
15+
#include <optional>
16+
#include <string>
1517
#include <utility>
1618

1719
namespace nabto {
1820
namespace webrtc {
1921
namespace util {
2022

21-
nabto::webrtc::SignalingHttpClientPtr CurlHttpClient::create() {
22-
return std::make_shared<CurlHttpClient>();
23+
nabto::webrtc::SignalingHttpClientPtr CurlHttpClient::create(
24+
std::optional<std::string> caBundle) {
25+
return std::make_shared<CurlHttpClient>(caBundle);
2326
}
2427

25-
CurlHttpClient::CurlHttpClient() : curl_(CurlAsync::create()) {}
28+
CurlHttpClient::CurlHttpClient(std::optional<std::string>& caBundle)
29+
: curl_(CurlAsync::create()), caBundle_(caBundle) {}
2630

2731
CurlHttpClient::~CurlHttpClient() {
2832
if (curlReqHeaders_ != nullptr) {
@@ -63,6 +67,14 @@ bool CurlHttpClient::sendRequest(
6367
return false;
6468
}
6569

70+
if (caBundle_.has_value()) {
71+
res = curl_easy_setopt(curl, CURLOPT_CAINFO, caBundle_.value().c_str());
72+
if (res != CURLE_OK) {
73+
NPLOGE << "Failed to set CA bundle with: " << curl_easy_strerror(res);
74+
return false;
75+
}
76+
}
77+
6678
res = curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFunc);
6779

6880
if (res != CURLE_OK) {

sdk/src/signaling_util/std_timer/include/nabto/webrtc/util/std_timer.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ namespace util {
1616
class StdTimer : public nabto::webrtc::SignalingTimer,
1717
public std::enable_shared_from_this<StdTimer> {
1818
public:
19-
~StdTimer() {}
19+
~StdTimer() {
20+
if (timer_.joinable()) {
21+
timer_.join();
22+
timer_ = std::thread();
23+
}
24+
}
2025

2126
void setTimeout(uint32_t timeoutMs, std::function<void()> cb) override {
2227
auto self = shared_from_this();

0 commit comments

Comments
 (0)