Browse Source

Allow WebSocket connect with no sub-protocols.

Fabio Alessandrelli 7 years ago
parent
commit
6bc97cc7cc

+ 8 - 10
modules/websocket/emws_client.cpp

@@ -62,25 +62,23 @@ EMSCRIPTEN_KEEPALIVE void _esws_on_close(void *obj, int code, char *reason, int
 
 Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) {
 
+	String proto_string = p_protocols.join(",");
 	String str = "ws://";
-	String proto_string = "";
 
 	if (p_ssl)
 		str = "wss://";
 	str += p_host + ":" + itos(p_port) + p_path;
-	for (int i = 0; i < p_protocols.size(); i++) {
-		proto_string += p_protocols[i];
-		proto_string += ",";
-	}
-	if (proto_string == "")
-		proto_string = "binary,";
-
-	proto_string = proto_string.substr(0, proto_string.length() - 1);
 
 	_is_connecting = true;
 	/* clang-format off */
 	int peer_sock = EM_ASM_INT({
-		var socket = new WebSocket(UTF8ToString($1), UTF8ToString($2).split(","));
+		var proto_str = UTF8ToString($2);
+		var socket = null;
+		if (proto_str) {
+			socket = new WebSocket(UTF8ToString($1), proto_str.split(","));
+		} else {
+			socket = new WebSocket(UTF8ToString($1));
+		}
 		var c_ptr = Module.IDHandler.get($0);
 		socket.binaryType = "arraybuffer";
 

+ 8 - 7
modules/websocket/lws_client.cpp

@@ -48,12 +48,10 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
 
 	ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER);
 
-	// prepare protocols
-	if (p_protocols.size() == 0) // default to binary protocol
-		p_protocols.append("binary");
+	// Prepare protocols
 	_lws_make_protocols(this, &LWSClient::_lws_gd_callback, p_protocols, &_lws_ref);
 
-	// init lws client
+	// Init lws client
 	struct lws_context_creation_info info;
 	struct lws_client_connect_info i;
 
@@ -87,7 +85,10 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
 	strncpy(pbuf, p_path.utf8().get_data(), 2048);
 
 	i.context = context;
-	i.protocol = _lws_ref->lws_names;
+	if (p_protocols.size() > 0)
+		i.protocol = _lws_ref->lws_names;
+	else
+		i.protocol = NULL;
 	i.address = abuf;
 	i.host = hbuf;
 	i.path = pbuf;
@@ -134,13 +135,13 @@ int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, voi
 		case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
 			_on_error();
 			destroy_context();
-			return -1; // we should close the connection (would probably happen anyway)
+			return -1; // We should close the connection (would probably happen anyway)
 
 		case LWS_CALLBACK_CLIENT_CLOSED:
 			peer->close();
 			destroy_context();
 			_on_disconnect();
-			return 0; // we can end here
+			return 0; // We can end here
 
 		case LWS_CALLBACK_CLIENT_RECEIVE:
 			peer->read_wsi(in, len);

+ 24 - 23
modules/websocket/lws_helper.h

@@ -105,53 +105,54 @@ static bool _lws_poll(struct lws_context *context, _LWSRef *ref) {
 }
 
 /*
- * prepare the protocol_structs to be fed to context
- * also prepare the protocol string used by the client
+ * Prepare the protocol_structs to be fed to context.
+ * Also prepare the protocol string used by the client.
  */
 static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) {
-	/* the input strings might go away after this call,
-	 * we need to copy them. Will clear them when
-	 * destroying the context */
+	// The input strings might go away after this call, we need to copy them.
+	// We will clear them when destroying the context.
 	int i;
 	int len = p_names.size();
 	size_t data_size = sizeof(struct LWSPeer::PeerData);
 	PoolVector<String>::Read pnr = p_names.read();
 
-	/*
-	 * This is a reference connecting the object with lws
-	 * keep track of status, mallocs, etc.
-	 * Must survive as long the context
-	 * Must be freed manually when context creation fails.
-	 */
+	// This is a reference connecting the object with lws keep track of status, mallocs, etc.
+	// Must survive as long the context.
+	// Must be freed manually when context creation fails.
 	_LWSRef *ref = _lws_create_ref(p_obj);
 
-	/* LWS protocol structs */
+	// LWS protocol structs.
 	ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2));
 	memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2));
 
 	CharString strings = p_names.join(",").ascii();
 	int str_len = strings.length();
 
-	/* Joined string of protocols, double the size: comma separated first, NULL separated last */
-	ref->lws_names = (char *)memalloc((str_len + 1) * 2); /* plus the terminator */
+	// Joined string of protocols, double the size: comma separated first, NULL separated last
+	ref->lws_names = (char *)memalloc((str_len + 1) * 2); // Plus the terminator
 
 	char *names_ptr = ref->lws_names;
 	struct lws_protocols *structs_ptr = ref->lws_structs;
 
-	copymem(names_ptr, strings.get_data(), str_len);
-	names_ptr[str_len] = '\0'; /* NULL terminator */
-	/* NULL terminated strings to be used in protocol structs */
-	copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
-	names_ptr[(str_len * 2) + 1] = '\0'; /* NULL terminator */
+	// Comma separated protocols string to be used in client Sec-WebSocket-Protocol header
+	if (str_len > 0)
+		copymem(names_ptr, strings.get_data(), str_len);
+	names_ptr[str_len] = '\0'; // NULL terminator
+
+	// NULL terminated protocol strings to be used in protocol structs
+	if (str_len > 0)
+		copymem(&names_ptr[str_len + 1], strings.get_data(), str_len);
+	names_ptr[(str_len * 2) + 1] = '\0'; // NULL terminator
 	int pos = str_len + 1;
 
-	/* the first protocol is always http-only */
-	structs_ptr[0].name = "http-only";
+	// The first protocol is the default for any http request (before upgrade).
+	// It is also used as the websocket protocol when no subprotocol is specified.
+	structs_ptr[0].name = "default";
 	structs_ptr[0].callback = p_callback;
 	structs_ptr[0].per_session_data_size = data_size;
 	structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE;
 	structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE;
-	/* add user defined protocols */
+	// Add user defined protocols
 	for (i = 0; i < len; i++) {
 		structs_ptr[i + 1].name = (const char *)&names_ptr[pos];
 		structs_ptr[i + 1].callback = p_callback;
@@ -161,7 +162,7 @@ static void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback,
 		pos += pnr[i].ascii().length() + 1;
 		names_ptr[pos - 1] = '\0';
 	}
-	/* add protocols terminator */
+	// Add protocols terminator
 	structs_ptr[len + 1].name = NULL;
 	structs_ptr[len + 1].callback = NULL;
 	structs_ptr[len + 1].per_session_data_size = 0;

+ 0 - 3
modules/websocket/lws_server.cpp

@@ -41,9 +41,6 @@ Error LWSServer::listen(int p_port, PoolVector<String> p_protocols, bool gd_mp_a
 	struct lws_context_creation_info info;
 	memset(&info, 0, sizeof info);
 
-	if (p_protocols.size() == 0) // default to binary protocol
-		p_protocols.append(String("binary"));
-
 	// Prepare lws protocol structs
 	_lws_make_protocols(this, &LWSServer::_lws_gd_callback, p_protocols, &_lws_ref);