瀏覽代碼

Merge pull request #278 from hhgyu/add-support-protocols

support Subprotocols
Paul-Louis Ageneau 4 年之前
父節點
當前提交
ffe202a6a2
共有 4 個文件被更改,包括 30 次插入5 次删除
  1. 1 0
      include/rtc/websocket.hpp
  2. 7 0
      src/websocket.cpp
  3. 15 4
      src/wstransport.cpp
  4. 7 1
      src/wstransport.hpp

+ 1 - 0
include/rtc/websocket.hpp

@@ -49,6 +49,7 @@ public:
 
 	struct Configuration {
 		bool disableTlsVerification = false; // if true, don't verify the TLS certificate
+		std::optional<std::vector<string>> protocols = std::nullopt;
 	};
 
 	WebSocket(std::optional<Configuration> config = nullopt);

+ 7 - 0
src/websocket.cpp

@@ -291,7 +291,14 @@ shared_ptr<WsTransport> WebSocket::initWsTransport() {
 		shared_ptr<Transport> lower = std::atomic_load(&mTlsTransport);
 		if (!lower)
 			lower = std::atomic_load(&mTcpTransport);
+
+		auto wsConfig = WsTransport::Configuration();
+		if(mConfig.protocols) {
+			wsConfig.protocols = *mConfig.protocols;
+		}
+
 		auto transport = std::make_shared<WsTransport>(
+			wsConfig,
 		    lower, mHost, mPath, weak_bind(&WebSocket::incoming, this, _1),
 		    [this, weak_this = weak_from_this()](State state) {
 			    auto shared_this = weak_this.lock();

+ 15 - 4
src/wstransport.cpp

@@ -29,6 +29,7 @@
 #include <map>
 #include <random>
 #include <regex>
+#include <numeric>
 
 #ifdef _WIN32
 #include <winsock2.h>
@@ -53,9 +54,9 @@ using std::to_string;
 using random_bytes_engine =
     std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned short>;
 
-WsTransport::WsTransport(std::shared_ptr<Transport> lower, string host, string path,
+WsTransport::WsTransport(std::optional<Configuration> config, std::shared_ptr<Transport> lower, string host, string path,
                          message_callback recvCallback, state_callback stateCallback)
-    : Transport(lower, std::move(stateCallback)), mHost(std::move(host)), mPath(std::move(path)) {
+    : Transport(lower, std::move(stateCallback)), mHost(std::move(host)), mPath(std::move(path)), mConfig(config ? std::move(*config) : Configuration()) {
 	onRecv(recvCallback);
 
 	PLOG_DEBUG << "Initializing WebSocket transport";
@@ -164,6 +165,15 @@ bool WsTransport::sendHttpRequest() {
 	auto k = reinterpret_cast<uint8_t *>(key.data());
 	std::generate(k, k + key.size(), [&]() { return uint8_t(generator()); });
 
+	string appendHeader = "";
+	if(mConfig.protocols.size() > 0) {
+		appendHeader += "Sec-WebSocket-Protocol: " +
+						std::accumulate(mConfig.protocols.begin(), mConfig.protocols.end(), string(), [](const string& a, const string& b) -> string { 
+							return a + (a.length() > 0 ? "," : "") + b; 
+						}) +
+						"\r\n";
+	}
+	
 	const string request = "GET " + mPath +
 	                       " HTTP/1.1\r\n"
 	                       "Host: " +
@@ -174,8 +184,9 @@ bool WsTransport::sendHttpRequest() {
 	                       "Sec-WebSocket-Version: 13\r\n"
 	                       "Sec-WebSocket-Key: " +
 	                       to_base64(key) +
-	                       "\r\n"
-	                       "\r\n";
+	                       "\r\n" +
+						   std::move(appendHeader) +
+						   "\r\n";
 
 	auto data = reinterpret_cast<const byte *>(request.data());
 	auto size = request.size();

+ 7 - 1
src/wstransport.hpp

@@ -31,7 +31,11 @@ class TlsTransport;
 
 class WsTransport : public Transport {
 public:
-	WsTransport(std::shared_ptr<Transport> lower, string host, string path,
+	struct Configuration {
+		std::vector<string> protocols;
+	};
+
+	WsTransport(std::optional<Configuration> config, std::shared_ptr<Transport> lower, string host, string path,
 	            message_callback recvCallback, state_callback stateCallback);
 	~WsTransport();
 
@@ -74,6 +78,8 @@ private:
 	binary mBuffer;
 	binary mPartial;
 	Opcode mPartialOpcode;
+
+	const Configuration mConfig;
 };
 
 } // namespace rtc