浏览代码

Cleanup and reformatting

Paul-Louis Ageneau 4 年之前
父节点
当前提交
244c834992
共有 9 个文件被更改,包括 125 次插入99 次删除
  1. 21 11
      include/rtc/description.hpp
  2. 31 15
      include/rtc/rtp.hpp
  3. 1 1
      include/rtc/websocket.hpp
  4. 37 33
      src/description.cpp
  5. 7 9
      src/dtlssrtptransport.cpp
  6. 1 1
      src/rtcp.cpp
  7. 5 6
      src/websocket.cpp
  8. 18 19
      src/wstransport.cpp
  9. 4 4
      src/wstransport.hpp

+ 21 - 11
include/rtc/description.hpp

@@ -32,6 +32,15 @@
 
 namespace rtc {
 
+const string DEFAULT_AUDIO_PROFILE =
+    "minptime=10;maxaveragebitrate=96000;stereo=1;sprop-stereo=1;useinbandfec=1";
+
+// Use Constrained Baseline profile Level 4.2 (necessary for Firefox)
+// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#Supported_video_codecs
+// TODO: Should be 42E0 but 42C0 appears to be more compatible. Investigate this.
+const string DEFAULT_VIDEO_PROFILE =
+    "profile-level-id=42e01f;packetization-mode=1;level-asymmetry-allowed=1";
+
 class RTC_CPP_EXPORT Description {
 public:
 	enum class Type { Unspec, Offer, Answer, Pranswer, Rollback };
@@ -131,8 +140,10 @@ public:
 
 		void removeFormat(const string &fmt);
 
-		void addSSRC(uint32_t ssrc, std::optional<std::string> name, std::optional<std::string> msid=std::nullopt);
-		void replaceSSRC(uint32_t oldSSRC, uint32_t ssrc, std::optional<std::string> name, std::optional<std::string> msid=std::nullopt);
+		void addSSRC(uint32_t ssrc, std::optional<string> name,
+		             std::optional<string> msid = nullopt);
+		void replaceSSRC(uint32_t oldSSRC, uint32_t ssrc, std::optional<string> name,
+		                 std::optional<string> msid = nullopt);
 		bool hasSSRC(uint32_t ssrc);
 		std::vector<uint32_t> getSSRCs();
 
@@ -141,7 +152,8 @@ public:
 
 		bool hasPayloadType(int payloadType) const;
 
-		void addRTXCodec(unsigned int payloadType, unsigned int originalPayloadType, unsigned int clockRate);
+		void addRTXCodec(unsigned int payloadType, unsigned int originalPayloadType,
+		                 unsigned int clockRate);
 
 		virtual void parseSdpLine(string_view line) override;
 
@@ -151,7 +163,7 @@ public:
 
 			void removeFB(const string &string);
 			void addFB(const string &string);
-			void addAttribute(std::string attr) { fmtps.emplace_back(attr); }
+			void addAttribute(string attr) { fmtps.emplace_back(std::move(attr)); }
 
 			int pt;
 			string format;
@@ -190,8 +202,9 @@ public:
 	public:
 		Audio(string mid = "audio", Direction dir = Direction::SendOnly);
 
-		void addAudioCodec(int payloadType, const string &codec, const std::optional<std::string>& profile=
-		        "minptime=10; maxaveragebitrate=96000; stereo=1; sprop-stereo=1; useinbandfec=1");
+		void addAudioCodec(int payloadType, string codec,
+		                   std::optional<string> profile = DEFAULT_AUDIO_PROFILE);
+
 		void addOpusCodec(int payloadType);
 	};
 
@@ -199,11 +212,8 @@ public:
 	public:
 		Video(string mid = "video", Direction dir = Direction::SendOnly);
 
-		// Use Constrained Baseline profile Level 4.2 (necessary for Firefox)
-		// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#Supported_video_codecs
-		// TODO: Should be 42E0 but 42C0 appears to be more compatible. Investigate this.
-		void addVideoCodec(int payloadType, const string &codec, const std::optional<std::string>&
-		        profile="profile-level-id=42e01f;packetization-mode=1;level-asymmetry-allowed=1");
+		void addVideoCodec(int payloadType, string codec,
+		                   std::optional<string> profile = DEFAULT_VIDEO_PROFILE);
 
 		void addH264Codec(int payloadType);
 		void addVP8Codec(int payloadType);

+ 31 - 15
include/rtc/rtp.hpp

@@ -66,10 +66,17 @@ public:
 	inline uint32_t ssrc() const { return ntohl(_ssrc); }
 
 	inline size_t getSize() const {
-		return ((char *)&csrc) - ((char *)this) + sizeof(SSRC) * csrcCount();
+		return reinterpret_cast<const char *>(&csrc) - reinterpret_cast<const char *>(this) +
+		       sizeof(SSRC) * csrcCount();
 	}
 
-	char *getBody() const { return ((char *)&csrc) + sizeof(SSRC) * csrcCount(); }
+	[[nodiscard]] char *getBody() {
+		return reinterpret_cast<char *>(&csrc) + sizeof(SSRC) * csrcCount();
+	}
+
+	[[nodiscard]] const char *getBody() const {
+		return reinterpret_cast<const char *>(&csrc) + sizeof(SSRC) * csrcCount();
+	}
 
 	inline void setSeqNumber(uint16_t newSeqNo) { _seqNumber = htons(newSeqNo); }
 	inline void setPayloadType(uint8_t newPayloadType) {
@@ -113,22 +120,23 @@ public:
 		setDelaySinceSR(uint32_t(lastSR_DELAY));
 
 		// The delay, expressed in units of 1/65536 seconds
-		//		  this->delaySinceLastReport = lastSR_DELAY;
+		// this->delaySinceLastReport = lastSR_DELAY;
 	}
 
 	inline void setSSRC(SSRC in_ssrc) { this->ssrc = htonl(in_ssrc); }
-	inline SSRC getSSRC() const { return ntohl(ssrc); }
+	[[nodiscard]] inline SSRC getSSRC() const { return ntohl(ssrc); }
 
 	inline void setPacketsLost([[maybe_unused]] unsigned int packetsLost,
 	                           [[maybe_unused]] unsigned int totalPackets) {
 		// TODO Implement loss percentages.
 		_fractionLostAndPacketsLost = 0;
 	}
-	inline unsigned int getLossPercentage() const {
+
+	[[nodiscard]] inline unsigned int getLossPercentage() const {
 		// TODO Implement loss percentages.
 		return 0;
 	}
-	inline unsigned int getPacketLostCount() const {
+	[[nodiscard]] inline unsigned int getPacketLostCount() const {
 		// TODO Implement total packets lost.
 		return 0;
 	}
@@ -145,13 +153,13 @@ public:
 	inline void setJitter(uint32_t jitter) { _jitter = htonl(jitter); }
 
 	inline void setNTPOfSR(uint64_t ntp) { _lastReport = htonll(ntp >> 16u); }
-	inline uint32_t getNTPOfSR() const { return ntohl(_lastReport) << 16u; }
+	[[nodiscard]] inline uint32_t getNTPOfSR() const { return ntohl(_lastReport) << 16u; }
 
 	inline void setDelaySinceSR(uint32_t sr) {
 		// The delay, expressed in units of 1/65536 seconds
 		_delaySinceLastReport = htonl(sr);
 	}
-	inline uint32_t getDelaySinceSR() const { return ntohl(_delaySinceLastReport); }
+	[[nodiscard]] inline uint32_t getDelaySinceSR() const { return ntohl(_delaySinceLastReport); }
 
 	inline void log() const {
 		PLOG_VERBOSE << "RTCP report block: "
@@ -242,8 +250,10 @@ public:
 		this->_senderSSRC = htonl(senderSSRC);
 	}
 
-	inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
-	inline const RTCP_ReportBlock *getReportBlock(int num) const { return &_reportBlocks + num; }
+	[[nodiscard]] inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
+	[[nodiscard]] inline const RTCP_ReportBlock *getReportBlock(int num) const {
+		return &_reportBlocks + num;
+	}
 
 	[[nodiscard]] inline size_t getSize() const {
 		// "length" in packet is one less than the number of 32 bit words in the packet.
@@ -280,8 +290,10 @@ private:
 	RTCP_ReportBlock _reportBlocks;
 
 public:
-	inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
-	inline const RTCP_ReportBlock *getReportBlock(int num) const { return &_reportBlocks + num; }
+	[[nodiscard]] inline RTCP_ReportBlock *getReportBlock(int num) { return &_reportBlocks + num; }
+	[[nodiscard]] inline const RTCP_ReportBlock *getReportBlock(int num) const {
+		return &_reportBlocks + num;
+	}
 
 	inline SSRC senderSSRC() const { return ntohl(_senderSSRC); }
 	inline void setSenderSSRC(SSRC ssrc) { this->_senderSSRC = htonl(ssrc); }
@@ -477,11 +489,15 @@ public:
 		return ntohs(*(uint16_t *)(header.getBody()));
 	}
 
-	char *getBody() { return header.getBody() + sizeof(uint16_t); }
+	[[nodiscard]] char *getBody() { return header.getBody() + sizeof(uint16_t); }
 
-	size_t getBodySize(size_t totalSize) { return totalSize - ((char *)getBody() - (char *)this); }
+	[[nodiscard]] const char *getBody() const { return header.getBody() + sizeof(uint16_t); }
+
+	[[nodiscard]] size_t getBodySize(size_t totalSize) {
+		return totalSize - (getBody() - reinterpret_cast<char *>(this));
+	}
 
-	RTP &getHeader() { return header; }
+	[[nodiscard]] RTP &getHeader() { return header; }
 
 	size_t normalizePacket(size_t totalSize, SSRC originalSSRC, uint8_t originalPayloadType) {
 		header.setSeqNumber(getOriginalSeqNo());

+ 1 - 1
include/rtc/websocket.hpp

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

+ 37 - 33
src/description.cpp

@@ -29,13 +29,13 @@
 #include <unordered_map>
 
 using std::shared_ptr;
-using std::size_t;
-using std::string;
-using std::string_view;
 using std::chrono::system_clock;
 
 namespace {
 
+using std::string;
+using std::string_view;
+
 inline bool match_prefix(string_view str, string_view prefix) {
 	return str.size() >= prefix.size() &&
 	       std::mismatch(prefix.begin(), prefix.end(), str.begin()).first == prefix.end();
@@ -483,8 +483,7 @@ string Description::Entry::generateSdpLines(string_view eol) const {
 	}
 
 	for (const auto &attr : mAttributes) {
-		if (attr.find("extmap") == std::string::npos &&
-		    attr.find("rtcp-rsize") == std::string::npos)
+		if (attr.find("extmap") == string::npos && attr.find("rtcp-rsize") == string::npos)
 			sdp << "a=" << attr << eol;
 	}
 
@@ -519,7 +518,8 @@ Description::Entry::removeAttribute(std::vector<string>::iterator it) {
 	return mAttributes.erase(it);
 }
 
-void Description::Media::addSSRC(uint32_t ssrc, std::optional<std::string> name, std::optional<std::string> msid) {
+void Description::Media::addSSRC(uint32_t ssrc, std::optional<string> name,
+                                 std::optional<string> msid) {
 	if (name)
 		mAttributes.emplace_back("ssrc:" + std::to_string(ssrc) + " cname:" + *name);
 	else
@@ -531,7 +531,8 @@ void Description::Media::addSSRC(uint32_t ssrc, std::optional<std::string> name,
 	mSsrcs.emplace_back(ssrc);
 }
 
-void Description::Media::replaceSSRC(uint32_t oldSSRC, uint32_t  ssrc, std::optional<std::string> name, std::optional<std::string> msid) {
+void Description::Media::replaceSSRC(uint32_t oldSSRC, uint32_t ssrc, std::optional<string> name,
+                                     std::optional<string> msid) {
 	auto it = mAttributes.begin();
 	while (it != mAttributes.end()) {
 		if (it->find("ssrc:" + std::to_string(oldSSRC)) == 0) {
@@ -543,13 +544,13 @@ void Description::Media::replaceSSRC(uint32_t oldSSRC, uint32_t  ssrc, std::opti
 }
 
 void Description::Media::removeSSRC(uint32_t oldSSRC) {
-    auto it = mAttributes.begin();
-    while (it != mAttributes.end()) {
-        if (it->find("ssrc:" + std::to_string(oldSSRC)) == 0) {
-            it = mAttributes.erase(it);
-        } else
-            it++;
-    }
+	auto it = mAttributes.begin();
+	while (it != mAttributes.end()) {
+		if (it->find("ssrc:" + std::to_string(oldSSRC)) == 0) {
+			it = mAttributes.erase(it);
+		} else
+			it++;
+	}
 }
 
 bool Description::Media::hasSSRC(uint32_t ssrc) {
@@ -702,17 +703,17 @@ void Description::Media::removeFormat(const string &fmt) {
 	}
 }
 
-void Description::Video::addVideoCodec(int payloadType, const string &codec, const std::optional<std::string>& profile) {
+void Description::Video::addVideoCodec(int payloadType, string codec,
+                                       std::optional<string> profile) {
 	RTPMap map(std::to_string(payloadType) + ' ' + codec + "/90000");
 	map.addFB("nack");
 	map.addFB("nack pli");
 	//    map.addFB("ccm fir");
 	map.addFB("goog-remb");
 	if (profile)
-	    map.fmtps.emplace_back(*profile);
-    addRTPMap(map);
+		map.fmtps.emplace_back(*profile);
+	addRTPMap(map);
 
-	//	// RTX Packets
 	/* TODO
 	 *  TIL that Firefox does not properly support the negotiation of RTX! It works, but doesn't
 	 * negotiate the SSRC so we have no idea what SSRC is RTX going to be. Three solutions: One) we
@@ -720,31 +721,34 @@ void Description::Video::addVideoCodec(int payloadType, const string &codec, con
 	 * rebuild the original packet before we send it distribute it to each track. Three) we complain
 	 * to mozilla. This one probably won't do much.
 	 */
-	//    RTPMap rtx(std::to_string(payloadType+1) + " rtx/90000");
-	//    // TODO rtx-time is how long can a request be stashed for before needing to resend it.
-	//    Needs to be parameterized rtx.addAttribute("apt=" + std::to_string(payloadType) +
-	//    ";rtx-time=3000"); addRTPMap(rtx);
+	// RTX Packets
+	// RTPMap rtx(std::to_string(payloadType+1) + " rtx/90000");
+	// // TODO rtx-time is how long can a request be stashed for before needing to resend it.
+	// Needs to be parameterized rtx.addAttribute("apt=" + std::to_string(payloadType) +
+	// ";rtx-time=3000"); addRTPMap(rtx);
 }
 
-void Description::Audio::addAudioCodec(int payloadType, const string &codec, const std::optional<std::string>& profile) {
+void Description::Audio::addAudioCodec(int payloadType, string codec,
+                                       std::optional<string> profile) {
 	// TODO This 48000/2 should be parameterized
 	RTPMap map(std::to_string(payloadType) + ' ' + codec + "/48000/2");
 	if (profile)
-	    map.fmtps.emplace_back(*profile);
+		map.fmtps.emplace_back(*profile);
 	addRTPMap(map);
 }
 
-void Description::Media::addRTXCodec(unsigned int payloadType, unsigned int originalPayloadType, unsigned int clockRate) {
-    RTPMap map(std::to_string(payloadType) + " RTX/" + std::to_string(clockRate));
-    map.fmtps.emplace_back("apt=" + std::to_string(originalPayloadType));
-    addRTPMap(map);
+void Description::Media::addRTXCodec(unsigned int payloadType, unsigned int originalPayloadType,
+                                     unsigned int clockRate) {
+	RTPMap map(std::to_string(payloadType) + " RTX/" + std::to_string(clockRate));
+	map.fmtps.emplace_back("apt=" + std::to_string(originalPayloadType));
+	addRTPMap(map);
 }
 
 void Description::Video::addH264Codec(int pt) { addVideoCodec(pt, "H264"); }
 
-void Description::Video::addVP8Codec(int payloadType) { addVideoCodec(payloadType, "VP8"); }
+void Description::Video::addVP8Codec(int payloadType) { addVideoCodec(payloadType, "VP8", nullopt); }
 
-void Description::Video::addVP9Codec(int payloadType) { addVideoCodec(payloadType, "VP9"); }
+void Description::Video::addVP9Codec(int payloadType) { addVideoCodec(payloadType, "VP9", nullopt); }
 
 void Description::Media::setBitrate(int bitrate) { mBas = bitrate; }
 
@@ -813,7 +817,7 @@ void Description::Media::parseSdpLine(string_view line) {
 		} else if (key == "rtcp-mux") {
 			// always added
 		} else if (key == "ssrc") {
-			mSsrcs.emplace_back(std::stoul((std::string)value));
+			mSsrcs.emplace_back(std::stoul(string(value)));
 		} else {
 			Entry::parseSdpLine(line);
 		}
@@ -833,7 +837,7 @@ std::vector<uint32_t> Description::Media::getSSRCs() {
 	for (auto &val : mAttributes) {
 		PLOG_DEBUG << val;
 		if (val.find("ssrc:") == 0) {
-			vec.emplace_back(std::stoul((std::string)val.substr(5, val.find(" "))));
+			vec.emplace_back(std::stoul(string(val.substr(5, val.find(" ")))));
 		}
 	}
 	return vec;
@@ -857,7 +861,7 @@ Description::Media::RTPMap::RTPMap(string_view mline) { setMLine(mline); }
 void Description::Media::RTPMap::removeFB(const string &str) {
 	auto it = rtcpFbs.begin();
 	while (it != rtcpFbs.end()) {
-		if (it->find(str) != std::string::npos) {
+		if (it->find(str) != string::npos) {
 			it = rtcpFbs.erase(it);
 		} else
 			it++;

+ 7 - 9
src/dtlssrtptransport.cpp

@@ -110,7 +110,7 @@ bool DtlsSrtpTransport::sendMedia(message_ptr message) {
 			if (err == srtp_err_status_replay_fail)
 				throw std::runtime_error("SRTCP packet is a replay");
 			else if (err == srtp_err_status_no_ctx) {
-				auto ssrc = ((RTCP_SR *)message->data())->senderSSRC();
+				auto ssrc = reinterpret_cast<RTCP_SR *>(message->data())->senderSSRC();
 				PLOG_INFO << "Adding SSRC to SRTCP: " << ssrc;
 				addSSRC(ssrc);
 				if ((err = srtp_protect_rtcp(mSrtpOut, message->data(), &size)))
@@ -127,7 +127,7 @@ bool DtlsSrtpTransport::sendMedia(message_ptr message) {
 			if (err == srtp_err_status_replay_fail)
 				throw std::runtime_error("Outgoing SRTP packet is a replay");
 			else if (err == srtp_err_status_no_ctx) {
-				auto ssrc = ((RTP *)message->data())->ssrc();
+				auto ssrc = reinterpret_cast<RTP *>(message->data())->ssrc();
 				PLOG_INFO << "Adding SSRC to RTP: " << ssrc;
 				addSSRC(ssrc);
 				if ((err = srtp_protect(mSrtpOut, message->data(), &size)))
@@ -196,7 +196,7 @@ void DtlsSrtpTransport::incoming(message_ptr message) {
 				else if (err == srtp_err_status_auth_fail)
 					PLOG_WARNING << "Incoming SRTCP packet failed authentication check";
 				else if (err == srtp_err_status_no_ctx) {
-					auto ssrc = ((RTCP_SR *)message->data())->senderSSRC();
+					auto ssrc = reinterpret_cast<RTCP_SR *>(message->data())->senderSSRC();
 					PLOG_INFO << "Adding SSRC to RTCP: " << ssrc;
 					addSSRC(ssrc);
 					if ((err = srtp_unprotect_rtcp(mSrtpIn, message->data(), &size)))
@@ -210,8 +210,7 @@ void DtlsSrtpTransport::incoming(message_ptr message) {
 			}
 			PLOG_VERBOSE << "Unprotected SRTCP packet, size=" << size;
 			message->type = Message::Type::Control;
-			auto rtp = (RTCP_SR *)message->data();
-			message->stream = rtp->senderSSRC();
+			message->stream = reinterpret_cast<RTCP_SR *>(message->data())->senderSSRC();
 		} else {
 			PLOG_VERBOSE << "Incoming SRTP packet, size=" << size;
 			if (srtp_err_status_t err = srtp_unprotect(mSrtpIn, message->data(), &size)) {
@@ -220,7 +219,7 @@ void DtlsSrtpTransport::incoming(message_ptr message) {
 				else if (err == srtp_err_status_auth_fail)
 					PLOG_WARNING << "Incoming SRTP packet failed authentication check";
 				else if (err == srtp_err_status_no_ctx) {
-					auto ssrc = ((RTP *)message->data())->ssrc();
+					auto ssrc = reinterpret_cast<RTP *>(message->data())->ssrc();
 					PLOG_INFO << "Adding SSRC to RTP: " << ssrc;
 					addSSRC(ssrc);
 					if ((err = srtp_unprotect(mSrtpIn, message->data(), &size)))
@@ -228,13 +227,12 @@ void DtlsSrtpTransport::incoming(message_ptr message) {
 						                         to_string(static_cast<int>(err)));
 				} else
 					PLOG_WARNING << "SRTP unprotect error, status=" << err
-					             << " SSRC=" << ((RTP *)message->data())->ssrc();
+					             << " SSRC=" << reinterpret_cast<RTP *>(message->data())->ssrc();
 				return;
 			}
 			PLOG_VERBOSE << "Unprotected SRTP packet, size=" << size;
 			message->type = Message::Type::Binary;
-			auto rtp = (RTP *)message->data();
-			message->stream = rtp->ssrc();
+			message->stream = reinterpret_cast<RTP *>(message->data())->ssrc();
 		}
 
 		message->resize(size);

+ 1 - 1
src/rtcp.cpp

@@ -126,7 +126,7 @@ bool RtcpReceivingSession::requestKeyframe() {
 
 void RtcpReceivingSession::pushPLI() {
 	auto msg = rtc::make_message(rtc::RTCP_PLI::size(), rtc::Message::Type::Control);
-	auto *pli = (rtc::RTCP_PLI *)msg->data();
+	auto *pli = reinterpret_cast<rtc::RTCP_PLI *>(msg->data());
 	pli->preparePacket(mSsrc);
 	send(msg);
 }

+ 5 - 6
src/websocket.cpp

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

+ 18 - 19
src/wstransport.cpp

@@ -27,9 +27,9 @@
 #include <iterator>
 #include <list>
 #include <map>
+#include <numeric>
 #include <random>
 #include <regex>
-#include <numeric>
 
 #ifdef _WIN32
 #include <winsock2.h>
@@ -54,17 +54,17 @@ using std::to_string;
 using random_bytes_engine =
     std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned short>;
 
-WsTransport::WsTransport(std::optional<Configuration> config, std::shared_ptr<Transport> lower, string host, string path,
+WsTransport::WsTransport(std::shared_ptr<Transport> lower, Configuration config,
                          message_callback recvCallback, state_callback stateCallback)
-    : Transport(lower, std::move(stateCallback)), mHost(std::move(host)), mPath(std::move(path)), mConfig(config ? std::move(*config) : Configuration()) {
+    : Transport(lower, std::move(stateCallback)), mConfig(std::move(config)) {
 	onRecv(recvCallback);
 
 	PLOG_DEBUG << "Initializing WebSocket transport";
 
-	if (mHost.empty())
+	if (mConfig.host.empty())
 		throw std::invalid_argument("WebSocket HTTP host cannot be empty");
 
-	if (mPath.empty())
+	if (mConfig.path.empty())
 		throw std::invalid_argument("WebSocket HTTP path cannot be empty");
 }
 
@@ -155,7 +155,7 @@ void WsTransport::close() {
 }
 
 bool WsTransport::sendHttpRequest() {
-	PLOG_DEBUG << "Sending WebSocket HTTP request for path " << mPath;
+	PLOG_DEBUG << "Sending WebSocket HTTP request for path " << mConfig.path;
 	changeState(State::Connecting);
 
 	auto seed = static_cast<unsigned int>(system_clock::now().time_since_epoch().count());
@@ -166,27 +166,26 @@ bool WsTransport::sendHttpRequest() {
 	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";
+	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 +
+
+	const string request = "GET " + mConfig.path +
 	                       " HTTP/1.1\r\n"
 	                       "Host: " +
-	                       mHost +
+	                       mConfig.host +
 	                       "\r\n"
 	                       "Connection: Upgrade\r\n"
 	                       "Upgrade: websocket\r\n"
 	                       "Sec-WebSocket-Version: 13\r\n"
 	                       "Sec-WebSocket-Key: " +
-	                       to_base64(key) +
-	                       "\r\n" +
-						   std::move(appendHeader) +
-						   "\r\n";
+	                       to_base64(key) + "\r\n" + std::move(appendHeader) + "\r\n";
 
 	auto data = reinterpret_cast<const byte *>(request.data());
 	auto size = request.size();

+ 4 - 4
src/wstransport.hpp

@@ -32,10 +32,12 @@ class TlsTransport;
 class WsTransport : public Transport {
 public:
 	struct Configuration {
+		string host;
+		string path = "/";
 		std::vector<string> protocols;
 	};
 
-	WsTransport(std::optional<Configuration> config, std::shared_ptr<Transport> lower, string host, string path,
+	WsTransport(std::shared_ptr<Transport> lower, Configuration config,
 	            message_callback recvCallback, state_callback stateCallback);
 	~WsTransport();
 
@@ -72,14 +74,12 @@ private:
 	void recvFrame(const Frame &frame);
 	bool sendFrame(const Frame &frame);
 
-	const string mHost;
-	const string mPath;
+	const Configuration mConfig;
 
 	binary mBuffer;
 	binary mPartial;
 	Opcode mPartialOpcode;
 
-	const Configuration mConfig;
 };
 
 } // namespace rtc