Browse Source

websocket compression client - part 1

Johan De Taeye 4 years ago
parent
commit
5ca309a31a
2 changed files with 148 additions and 24 deletions
  1. 24 0
      include/civetweb.h
  2. 124 24
      src/civetweb.c

+ 24 - 0
include/civetweb.h

@@ -1421,6 +1421,19 @@ mg_connect_websocket_client(const char *host,
                             mg_websocket_close_handler close_func,
                             void *user_data);
 
+CIVETWEB_API struct mg_connection *
+mg_connect_websocket_client_extensions(const char *host,
+                                       int port,
+                                       int use_ssl,
+                                       char *error_buffer,
+                                       size_t error_buffer_size,
+                                       const char *path,
+                                       const char *origin,
+                                       mg_websocket_data_handler data_func,
+                                       mg_websocket_close_handler close_func,
+                                       void *user_data,
+                                       const char *extensions);
+
 
 /* Connect to a TCP server as a client (can be used to connect to a HTTP server)
    Parameters:
@@ -1467,6 +1480,17 @@ CIVETWEB_API struct mg_connection *mg_connect_websocket_client_secure(
     mg_websocket_close_handler close_func,
     void *user_data);
 
+CIVETWEB_API struct mg_connection *
+mg_connect_websocket_client_secure_extensions(
+    const struct mg_client_options *client_options,
+    char *error_buffer,
+    size_t error_buffer_size,
+    const char *path,
+    const char *origin,
+    mg_websocket_data_handler data_func,
+    mg_websocket_close_handler close_func,
+    void *user_data,
+    const char *extensions);
 
 #if defined(MG_LEGACY_INTERFACE) /* 2019-11-02 */
 enum { TIMEOUT_INFINITE = -1 };

+ 124 - 24
src/civetweb.c

@@ -18172,37 +18172,18 @@ mg_connect_websocket_client_impl(const struct mg_client_options *client_options,
                                  const char *origin,
                                  mg_websocket_data_handler data_func,
                                  mg_websocket_close_handler close_func,
-                                 void *user_data)
+                                 void *user_data,
+                                 const char *extensions)
 {
 	struct mg_connection *conn = NULL;
 
 #if defined(USE_WEBSOCKET)
 	struct websocket_client_thread_data *thread_data;
 	static const char *magic = "x3JJHMbDL1EzLkh9GBhXDw==";
-	const char *handshake_req;
 
 	const char *host = client_options->host;
 	int i;
 
-	if (origin != NULL) {
-		handshake_req = "GET %s HTTP/1.1\r\n"
-		                "Host: %s\r\n"
-		                "Upgrade: websocket\r\n"
-		                "Connection: Upgrade\r\n"
-		                "Sec-WebSocket-Key: %s\r\n"
-		                "Sec-WebSocket-Version: 13\r\n"
-		                "Origin: %s\r\n"
-		                "\r\n";
-	} else {
-		handshake_req = "GET %s HTTP/1.1\r\n"
-		                "Host: %s\r\n"
-		                "Upgrade: websocket\r\n"
-		                "Connection: Upgrade\r\n"
-		                "Sec-WebSocket-Key: %s\r\n"
-		                "Sec-WebSocket-Version: 13\r\n"
-		                "\r\n";
-	}
-
 #if defined(__clang__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-nonliteral"
@@ -18228,7 +18209,68 @@ mg_connect_websocket_client_impl(const struct mg_client_options *client_options,
 		return NULL;
 	}
 
-	i = mg_printf(conn, handshake_req, path, host, magic, origin);
+	if (origin != NULL) {
+		if (extensions != NULL) {
+			i = mg_printf(conn,
+			              "GET %s HTTP/1.1\r\n"
+			              "Host: %s\r\n"
+			              "Upgrade: websocket\r\n"
+			              "Connection: Upgrade\r\n"
+			              "Sec-WebSocket-Key: %s\r\n"
+			              "Sec-WebSocket-Version: 13\r\n"
+			              "Sec-WebSocket-Extensions: %s\r\n"
+			              "Origin: %s\r\n"
+			              "\r\n",
+			              path,
+			              host,
+			              magic,
+			              extensions,
+			              origin);
+		} else {
+			i = mg_printf(conn,
+			              "GET %s HTTP/1.1\r\n"
+			              "Host: %s\r\n"
+			              "Upgrade: websocket\r\n"
+			              "Connection: Upgrade\r\n"
+			              "Sec-WebSocket-Key: %s\r\n"
+			              "Sec-WebSocket-Version: 13\r\n"
+			              "Origin: %s\r\n"
+			              "\r\n",
+			              path,
+			              host,
+			              magic,
+			              origin);
+		}
+	} else {
+
+		if (extensions != NULL) {
+			i = mg_printf(conn,
+			              "GET %s HTTP/1.1\r\n"
+			              "Host: %s\r\n"
+			              "Upgrade: websocket\r\n"
+			              "Connection: Upgrade\r\n"
+			              "Sec-WebSocket-Key: %s\r\n"
+			              "Sec-WebSocket-Version: 13\r\n"
+			              "Sec-WebSocket-Extensions: %s\r\n"
+			              "\r\n",
+			              path,
+			              host,
+			              magic,
+			              extensions);
+		} else {
+			i = mg_printf(conn,
+			              "GET %s HTTP/1.1\r\n"
+			              "Host: %s\r\n"
+			              "Upgrade: websocket\r\n"
+			              "Connection: Upgrade\r\n"
+			              "Sec-WebSocket-Key: %s\r\n"
+			              "Sec-WebSocket-Version: 13\r\n"
+			              "\r\n",
+			              path,
+			              host,
+			              magic);
+		}
+	}
 	if (i <= 0) {
 		mg_snprintf(conn,
 		            NULL, /* No truncation check for ebuf */
@@ -18354,7 +18396,8 @@ mg_connect_websocket_client(const char *host,
 	                                        origin,
 	                                        data_func,
 	                                        close_func,
-	                                        user_data);
+	                                        user_data,
+	                                        NULL);
 }
 
 
@@ -18380,9 +18423,66 @@ mg_connect_websocket_client_secure(
 	                                        origin,
 	                                        data_func,
 	                                        close_func,
-	                                        user_data);
+	                                        user_data,
+	                                        NULL);
+}
+
+struct mg_connection *
+mg_connect_websocket_client_extensions(const char *host,
+                                       int port,
+                                       int use_ssl,
+                                       char *error_buffer,
+                                       size_t error_buffer_size,
+                                       const char *path,
+                                       const char *origin,
+                                       mg_websocket_data_handler data_func,
+                                       mg_websocket_close_handler close_func,
+                                       void *user_data,
+                                       const char *extensions)
+{
+	struct mg_client_options client_options;
+	memset(&client_options, 0, sizeof(client_options));
+	client_options.host = host;
+	client_options.port = port;
+
+	return mg_connect_websocket_client_impl(&client_options,
+	                                        use_ssl,
+	                                        error_buffer,
+	                                        error_buffer_size,
+	                                        path,
+	                                        origin,
+	                                        data_func,
+	                                        close_func,
+	                                        user_data,
+	                                        extensions);
 }
 
+struct mg_connection *
+mg_connect_websocket_client_secure_extensions(
+    const struct mg_client_options *client_options,
+    char *error_buffer,
+    size_t error_buffer_size,
+    const char *path,
+    const char *origin,
+    mg_websocket_data_handler data_func,
+    mg_websocket_close_handler close_func,
+    void *user_data,
+    const char *extensions)
+{
+	if (!client_options) {
+		return NULL;
+	}
+	return mg_connect_websocket_client_impl(client_options,
+	                                        1,
+	                                        error_buffer,
+	                                        error_buffer_size,
+	                                        path,
+	                                        origin,
+	                                        data_func,
+	                                        close_func,
+	                                        user_data,
+	                                        extensions);
+}
 
 /* Prepare connection data structure */
 static void