ws connect has a new option to send HTTP headers + use WebSocketHttpHeaders instead of unordered_map<string, string>
This commit is contained in:
		| @@ -2,6 +2,14 @@ | ||||
| All notable changes to this project will be documented in this file. | ||||
|  | ||||
| ## [5.0.7] - 2019-08-23 | ||||
| - WebSocket: add new option to pass in extra HTTP headers when connecting. | ||||
| - `ws connect` add new option (-H, works like [curl](https://stackoverflow.com/questions/356705/how-to-send-a-header-using-a-http-request-through-a-curl-call)) to pass in extra HTTP headers when connecting  | ||||
|  | ||||
| If you run against `ws echo_server` you will see the headers being received printed in the terminal. | ||||
| ``` | ||||
| ws connect -H "foo: bar" -H "baz: buz" ws://127.0.0.1:8008 | ||||
| ``` | ||||
|  | ||||
| - CobraConnection: sets a unique id field for all messages sent to [cobra](https://github.com/machinezone/cobra). | ||||
| - CobraConnection: sets a counter as a field for each event published. | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							| @@ -510,3 +510,13 @@ idle connection. | ||||
| ``` | ||||
| webSocket.setHeartBeatPeriod(45); | ||||
| ``` | ||||
|  | ||||
| ### Supply extra HTTP headers. | ||||
|  | ||||
| You can set extra HTTP headers to be sent during the WebSocket handshake. | ||||
|  | ||||
| ``` | ||||
| WebSocketHttpHeaders headers; | ||||
| headers["foo"] = "bar"; | ||||
| webSocket.setExtraHeaders(headers); | ||||
| ``` | ||||
|   | ||||
| @@ -70,7 +70,7 @@ namespace ix | ||||
|         std::lock_guard<std::mutex> lock(_configMutex); | ||||
|         _url = url; | ||||
|     } | ||||
|     void WebSocket::setExtraHeaders(const std::unordered_map<std::string, std::string>& headers) | ||||
|     void WebSocket::setExtraHeaders(const WebSocketHttpHeaders& headers) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_configMutex); | ||||
|         _extraHeaders = headers; | ||||
|   | ||||
| @@ -21,7 +21,6 @@ | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <thread> | ||||
| #include <unordered_map> | ||||
|  | ||||
| namespace ix | ||||
| { | ||||
| @@ -45,8 +44,9 @@ namespace ix | ||||
|         ~WebSocket(); | ||||
|  | ||||
|         void setUrl(const std::string& url); | ||||
|         void setExtraHeaders(const std::unordered_map<std::string, std::string>& | ||||
|                                  headers); // send extra headers in client handshake request | ||||
|  | ||||
|         // send extra headers in client handshake request | ||||
|         void setExtraHeaders(const WebSocketHttpHeaders& headers); | ||||
|         void setPerMessageDeflateOptions( | ||||
|             const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions); | ||||
|         void setHeartBeatPeriod(int heartBeatPeriodSecs); | ||||
| @@ -114,7 +114,7 @@ namespace ix | ||||
|         WebSocketTransport _ws; | ||||
|  | ||||
|         std::string _url; | ||||
|         std::unordered_map<std::string, std::string> _extraHeaders; | ||||
|         WebSocketHttpHeaders _extraHeaders; | ||||
|  | ||||
|         WebSocketPerMessageDeflateOptions _perMessageDeflateOptions; | ||||
|         mutable std::mutex _configMutex; // protect all config variables access | ||||
|   | ||||
| @@ -88,7 +88,7 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     WebSocketInitResult WebSocketHandshake::clientHandshake(const std::string& url, | ||||
|                                                             const std::unordered_map<std::string, std::string>& extraHeaders, | ||||
|                                                             const WebSocketHttpHeaders& extraHeaders, | ||||
|                                                             const std::string& host, | ||||
|                                                             const std::string& path, | ||||
|                                                             int port, | ||||
|   | ||||
| @@ -53,7 +53,7 @@ namespace ix | ||||
|  | ||||
|         WebSocketInitResult clientHandshake( | ||||
|             const std::string& url, | ||||
|             const std::unordered_map<std::string, std::string>& extraHeaders, | ||||
|             const WebSocketHttpHeaders& extraHeaders, | ||||
|             const std::string& host, | ||||
|             const std::string& path, | ||||
|             int port, | ||||
|   | ||||
| @@ -129,7 +129,7 @@ namespace ix | ||||
|     // Client | ||||
|     WebSocketInitResult WebSocketTransport::connectToUrl( | ||||
|         const std::string& url, | ||||
|         const std::unordered_map<std::string, std::string>& headers, | ||||
|         const WebSocketHttpHeaders& headers, | ||||
|         int timeoutSecs) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_socketMutex); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| namespace ix | ||||
| @@ -78,7 +78,7 @@ namespace ix | ||||
|  | ||||
|         WebSocketInitResult connectToUrl( // Client | ||||
|             const std::string& url, | ||||
|             const std::unordered_map<std::string, std::string>& headers, | ||||
|             const WebSocketHttpHeaders& headers, | ||||
|             int timeoutSecs); | ||||
|         WebSocketInitResult connectToSocket(int fd, // Server | ||||
|                                             int timeoutSecs); | ||||
|   | ||||
| @@ -109,6 +109,7 @@ int main(int argc, char** argv) | ||||
|  | ||||
|     CLI::App* connectApp = app.add_subcommand("connect", "Connect to a remote server"); | ||||
|     connectApp->add_option("url", url, "Connection url")->required(); | ||||
|     connectApp->add_option("-H", headers, "Header")->join(); | ||||
|     connectApp->add_flag("-d", disableAutomaticReconnection, "Disable Automatic Reconnection"); | ||||
|     connectApp->add_flag("-x", disablePerMessageDeflate, "Disable per message deflate"); | ||||
|     connectApp->add_flag("-b", binaryMode, "Send in binary mode"); | ||||
| @@ -252,7 +253,7 @@ int main(int argc, char** argv) | ||||
|     } | ||||
|     else if (app.got_subcommand("connect")) | ||||
|     { | ||||
|         ret = ix::ws_connect_main(url, disableAutomaticReconnection, | ||||
|         ret = ix::ws_connect_main(url, headers, disableAutomaticReconnection, | ||||
|                                   disablePerMessageDeflate, binaryMode); | ||||
|     } | ||||
|     else if (app.got_subcommand("chat")) | ||||
|   | ||||
							
								
								
									
										1
									
								
								ws/ws.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								ws/ws.h
									
									
									
									
									
								
							| @@ -31,6 +31,7 @@ namespace ix | ||||
|     int ws_chat_main(const std::string& url, const std::string& user); | ||||
|  | ||||
|     int ws_connect_main(const std::string& url, | ||||
|                         const std::string& headers, | ||||
|                         bool disableAutomaticReconnection, | ||||
|                         bool disablePerMessageDeflate, | ||||
|                         bool binaryMode); | ||||
|   | ||||
| @@ -18,6 +18,7 @@ namespace ix | ||||
|     { | ||||
|         public: | ||||
|             WebSocketConnect(const std::string& _url, | ||||
|                              const std::string& headers, | ||||
|                              bool disableAutomaticReconnection, | ||||
|                              bool disablePerMessageDeflate, | ||||
|                              bool binaryMode); | ||||
| @@ -30,14 +31,17 @@ namespace ix | ||||
|  | ||||
|         private: | ||||
|             std::string _url; | ||||
|             WebSocketHttpHeaders _headers; | ||||
|             ix::WebSocket _webSocket; | ||||
|             bool _disablePerMessageDeflate; | ||||
|             bool _binaryMode; | ||||
|  | ||||
|             void log(const std::string& msg); | ||||
|             WebSocketHttpHeaders parseHeaders(const std::string& data); | ||||
|     }; | ||||
|  | ||||
|     WebSocketConnect::WebSocketConnect(const std::string& url, | ||||
|                                        const std::string& headers, | ||||
|                                        bool disableAutomaticReconnection, | ||||
|                                        bool disablePerMessageDeflate, | ||||
|                                        bool binaryMode) : | ||||
| @@ -49,6 +53,8 @@ namespace ix | ||||
|         { | ||||
|             _webSocket.disableAutomaticReconnection(); | ||||
|         } | ||||
|  | ||||
|         _headers = parseHeaders(headers); | ||||
|     } | ||||
|  | ||||
|     void WebSocketConnect::log(const std::string& msg) | ||||
| @@ -56,6 +62,31 @@ namespace ix | ||||
|         std::cout << msg << std::endl; | ||||
|     } | ||||
|  | ||||
|     WebSocketHttpHeaders WebSocketConnect::parseHeaders(const std::string& data) | ||||
|     { | ||||
|         WebSocketHttpHeaders headers; | ||||
|  | ||||
|         // Split by \n | ||||
|         std::string token; | ||||
|         std::stringstream tokenStream(data); | ||||
|  | ||||
|         while (std::getline(tokenStream, token)) | ||||
|         { | ||||
|             std::size_t pos = token.rfind(':'); | ||||
|  | ||||
|             // Bail out if last '.' is found | ||||
|             if (pos == std::string::npos) continue; | ||||
|  | ||||
|             auto key = token.substr(0, pos); | ||||
|             auto val = token.substr(pos+1); | ||||
|  | ||||
|             std::cerr << key << ": " << val << std::endl; | ||||
|             headers[key] = val; | ||||
|         } | ||||
|  | ||||
|         return headers; | ||||
|     } | ||||
|  | ||||
|     void WebSocketConnect::stop() | ||||
|     { | ||||
|         _webSocket.stop(); | ||||
| @@ -64,6 +95,7 @@ namespace ix | ||||
|     void WebSocketConnect::start() | ||||
|     { | ||||
|         _webSocket.setUrl(_url); | ||||
|         _webSocket.setExtraHeaders(_headers); | ||||
|  | ||||
|         if (_disablePerMessageDeflate) | ||||
|         { | ||||
| @@ -151,12 +183,14 @@ namespace ix | ||||
|     } | ||||
|  | ||||
|     int ws_connect_main(const std::string& url, | ||||
|                         const std::string& headers, | ||||
|                         bool disableAutomaticReconnection, | ||||
|                         bool disablePerMessageDeflate, | ||||
|                         bool binaryMode) | ||||
|     { | ||||
|         std::cout << "Type Ctrl-D to exit prompt..." << std::endl; | ||||
|         WebSocketConnect webSocketChat(url, | ||||
|                                        headers, | ||||
|                                        disableAutomaticReconnection, | ||||
|                                        disablePerMessageDeflate, | ||||
|                                        binaryMode); | ||||
|   | ||||
| @@ -44,7 +44,7 @@ namespace ix | ||||
|             if (pos == std::string::npos) continue; | ||||
|  | ||||
|             auto key = token.substr(0, pos); | ||||
|             auto val = token.substr(pos+2); | ||||
|             auto val = token.substr(pos+1); | ||||
|  | ||||
|             std::cerr << key << ": " << val << std::endl; | ||||
|             headers[key] = val; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user