[asterisk-commits] file: branch file/websocket r367977 - /team/file/websocket/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 30 12:29:18 CDT 2012


Author: file
Date: Wed May 30 12:29:14 2012
New Revision: 367977

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=367977
Log:
Incorporate review feedback.

Modified:
    team/file/websocket/res/res_http_websocket.c

Modified: team/file/websocket/res/res_http_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/file/websocket/res/res_http_websocket.c?view=diff&rev=367977&r1=367976&r2=367977
==============================================================================
--- team/file/websocket/res/res_http_websocket.c (original)
+++ team/file/websocket/res/res_http_websocket.c Wed May 30 12:29:14 2012
@@ -82,14 +82,18 @@
 static int protocol_hash_fn(const void *obj, const int flags)
 {
 	const struct websocket_protocol *protocol = obj;
-	return ast_str_case_hash(protocol->name);
+	const char *name = obj;
+
+	return ast_str_case_hash(flags & OBJ_KEY ? name : protocol->name);
 }
 
 /*! \brief Comparison function for protocols */
 static int protocol_cmp_fn(void *obj, void *arg, int flags)
 {
 	const struct websocket_protocol *protocol1 = obj, *protocol2 = arg;
-	return !strcasecmp(protocol1->name, protocol2->name) ? CMP_MATCH | CMP_STOP : 0;
+	const char *protocol = arg;
+
+	return !strcasecmp(protocol1->name, flags & OBJ_KEY ? protocol : protocol2->name) ? CMP_MATCH | CMP_STOP : 0;
 }
 
 /*! \brief Destructor function for protocols */
@@ -114,12 +118,12 @@
 
 int ast_websocket_add_protocol(const char *name, ast_websocket_callback callback)
 {
-	struct websocket_protocol tmp = { .name = (char*)name, }, *protocol;
+	struct websocket_protocol *protocol;
 
 	ao2_lock(protocols);
 
 	/* Ensure a second protocol handler is not registered for the same protocol */
-	if ((protocol = ao2_find(protocols, &tmp, OBJ_POINTER))) {
+	if ((protocol = ao2_find(protocols, name, OBJ_KEY | OBJ_NOLOCK))) {
 		ao2_ref(protocol, -1);
 		ao2_unlock(protocols);
 		return -1;
@@ -149,9 +153,9 @@
 
 int ast_websocket_remove_protocol(const char *name, ast_websocket_callback callback)
 {
-	struct websocket_protocol tmp = { .name = (char*)name, }, *protocol;
-
-	if (!(protocol = ao2_find(protocols, &tmp, OBJ_POINTER))) {
+	struct websocket_protocol *protocol;
+
+	if (!(protocol = ao2_find(protocols, name, OBJ_KEY))) {
 		return -1;
 	}
 
@@ -204,7 +208,7 @@
 		header_size += 8;
 	}
 
-	frame = alloca(header_size + actual_length);
+	frame = alloca(header_size);
 	memset(frame, 0, sizeof(*frame));
 
 	frame[0] = opcode | 0x80;
@@ -217,18 +221,20 @@
 		put_unaligned_uint64(&frame[2], htonl(actual_length));
 	}
 
-	memcpy(frame + header_size, payload, actual_length);
-
-	return (fwrite(frame, 1, header_size + actual_length, session->f) == header_size + actual_length) ? 0 : -1;
+	if (fwrite(frame, 1, header_size, session->f) != header_size) {
+		return -1;
+	}
+
+	if (fwrite(payload, 1, actual_length, session->f) != actual_length) {
+		return -1;
+	}
+
+	return 0;
 }
 
 void ast_websocket_reconstruct_enable(struct ast_websocket *session, size_t bytes)
 {
-	if (bytes > MAXIMUM_RECONSTRUCTION_CEILING) {
-		bytes = MAXIMUM_RECONSTRUCTION_CEILING;
-	}
-
-	session->reconstruct = bytes;
+	session->reconstruct = MIN(bytes, MAXIMUM_RECONSTRUCTION_CEILING);
 }
 
 void ast_websocket_reconstruct_disable(struct ast_websocket *session)
@@ -286,7 +292,7 @@
 	    *opcode == AST_WEBSOCKET_OPCODE_PING || *opcode == AST_WEBSOCKET_OPCODE_PONG) {
 		int fin = (buf[0] >> 7) & 1;
 		int mask_present = (buf[1] >> 7) & 1;
-		char *mask = &buf[2], *new_payload;
+		char *mask = NULL, *new_payload;
 		size_t remaining;
 
 		if (mask_present) {
@@ -313,8 +319,13 @@
 			}
 
 			*payload_len = ntohs(get_unaligned_uint16(&buf[2]));
-			mask = &buf[4];
-			*payload = &buf[8];
+
+			if (mask_present) {
+				mask = &buf[4];
+				*payload = &buf[8];
+			} else {
+				*payload = &buf[4];
+			}
 		} else if (*payload_len == 127) {
 			/* Use the next 8 bytes to get a uint64_t */
 			expected += 8;
@@ -325,10 +336,20 @@
 			}
 
 			*payload_len = ntohl(get_unaligned_uint64(&buf[2]));
-			mask = &buf[10];
-			*payload = &buf[12];
+
+			if (mask_present) {
+				mask = &buf[10];
+				*payload = &buf[12];
+			} else {
+				*payload = &buf[10];
+			}
 		} else if (*payload_len) {
-			*payload = &buf[6];
+			if (mask_present) {
+				mask = &buf[2];
+				*payload = &buf[6];
+			} else {
+				*payload = &buf[6];
+			}
 		}
 
 		/* Determine how much payload we need to read in as we may have already read some in */
@@ -481,26 +502,22 @@
 	} else if (ast_strlen_zero(requested_protocols)) {
 		ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - no protocols requested",
 			ast_sockaddr_stringify(&ser->remote_address));
-		fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-			"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+		fputs("HTTP/1.1 400 Bad Request\r\n"
+		      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 		return -1;
 	} else if (key1 && key2) {
 		/* Specification defined in http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76 and
 		 * http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00 -- not currently supported*/
 		ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - unsupported version '00/76' chosen",
 			ast_sockaddr_stringify(&ser->remote_address));
-		fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-			"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+		fputs("HTTP/1.1 400 Bad Request\r\n"
+		      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 		return 0;
 	}
 
 	/* Iterate through the requested protocols trying to find one that we have a handler for */
 	while ((protocol = strsep(&requested_protocols, ","))) {
-		struct websocket_protocol tmp;
-
-		tmp.name = ast_strip(protocol);
-
-		if ((protocol_handler = ao2_find(protocols, &tmp, OBJ_POINTER))) {
+		if ((protocol_handler = ao2_find(protocols, ast_strip(protocol), OBJ_KEY))) {
 			break;
 		}
 	}
@@ -509,8 +526,8 @@
 	if (!protocol_handler) {
 		ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - no protocols out of '%s' supported\n",
 			ast_sockaddr_stringify(&ser->remote_address), protos);
-		fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-			"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+		fputs("HTTP/1.1 400 Bad Request\r\n"
+		      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 		return 0;
 	}
 
@@ -526,8 +543,8 @@
 		if (!(session = ao2_alloc(sizeof(*session), session_destroy_fn))) {
 			ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted",
 				ast_sockaddr_stringify(&ser->remote_address));
-			fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-				"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+			fputs("HTTP/1.1 400 Bad Request\r\n"
+			      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 			ao2_ref(protocol_handler, -1);
 			return 0;
 		}
@@ -551,8 +568,8 @@
 		/* Specification defined in http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 or completely unknown */
 		ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - unsupported version '%d' chosen",
 			ast_sockaddr_stringify(&ser->remote_address), version ? version : 75);
-		fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-			"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+		fputs("HTTP/1.1 400 Bad Request\r\n"
+		      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 		ao2_ref(protocol_handler, -1);
 		return 0;
 	}
@@ -561,8 +578,8 @@
 	if (setsockopt(ser->fd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags))) {
 		ast_log(LOG_WARNING, "WebSocket connection from '%s' could not be accepted - failed to enable keepalive",
 			ast_sockaddr_stringify(&ser->remote_address));
-		fprintf(ser->f, "HTTP/1.1 400 Bad Request\r\n"
-			"Sec-WebSocket-Version: 7, 8, 13\r\n\r\n");
+		fputs("HTTP/1.1 400 Bad Request\r\n"
+		      "Sec-WebSocket-Version: 7, 8, 13\r\n\r\n", ser->f);
 		ao2_ref(session, -1);
 		ao2_ref(protocol_handler, -1);
 		return 0;




More information about the asterisk-commits mailing list