|
@@ -8076,14 +8076,19 @@ read_websocket(struct mg_connection *conn,
|
|
|
mg_set_thread_name("worker");
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
-mg_websocket_write(struct mg_connection *conn,
|
|
|
- int opcode,
|
|
|
- const char *data,
|
|
|
- size_t dataLen)
|
|
|
+static int
|
|
|
+mg_websocket_write_exec(struct mg_connection *conn,
|
|
|
+ int opcode,
|
|
|
+ const char *data,
|
|
|
+ size_t dataLen,
|
|
|
+ char mask)
|
|
|
{
|
|
|
- unsigned char header[10];
|
|
|
+ unsigned char header[14];
|
|
|
size_t headerLen = 1;
|
|
|
+ uint8_t masking_key[4];
|
|
|
+ unsigned char masked_data[dataLen];
|
|
|
+ const char* send_data;
|
|
|
+ size_t i = 0;
|
|
|
|
|
|
int retval = -1;
|
|
|
|
|
@@ -8107,6 +8112,29 @@ mg_websocket_write(struct mg_connection *conn,
|
|
|
headerLen = 10;
|
|
|
}
|
|
|
|
|
|
+ if(mask) {
|
|
|
+ /* add mask */
|
|
|
+ srand(time(NULL));
|
|
|
+ masking_key[0] = rand() & 0xff;
|
|
|
+ masking_key[1] = rand() & 0xff;
|
|
|
+ masking_key[2] = rand() & 0xff;
|
|
|
+ masking_key[3] = rand() & 0xff;
|
|
|
+
|
|
|
+ header[1] |= 0x80;
|
|
|
+ header[headerLen] = masking_key[0];
|
|
|
+ header[headerLen + 1] = masking_key[1];
|
|
|
+ header[headerLen + 2] = masking_key[2];
|
|
|
+ header[headerLen + 3] = masking_key[3];
|
|
|
+ headerLen += 4;
|
|
|
+ for (i = 0; i != dataLen; ++i) {
|
|
|
+ masked_data[i] = *data++ ^ masking_key[i&0x3];
|
|
|
+ }
|
|
|
+ send_data = (const char*)masked_data;
|
|
|
+ } else {
|
|
|
+ send_data = data;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/* Note that POSIX/Winsock's send() is threadsafe
|
|
|
* http://stackoverflow.com/questions/1981372/are-parallel-calls-to-send-recv-on-the-same-socket-valid
|
|
|
* but mongoose's mg_printf/mg_write is not (because of the loop in
|
|
@@ -8114,12 +8142,32 @@ mg_websocket_write(struct mg_connection *conn,
|
|
|
* outgoing buffer is full). */
|
|
|
(void)mg_lock_connection(conn);
|
|
|
retval = mg_write(conn, header, headerLen);
|
|
|
- retval = mg_write(conn, data, dataLen);
|
|
|
+ if (dataLen > 0) {
|
|
|
+ retval = mg_write(conn, send_data, dataLen);
|
|
|
+ }
|
|
|
mg_unlock_connection(conn);
|
|
|
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+mg_websocket_write(struct mg_connection *conn,
|
|
|
+ int opcode,
|
|
|
+ const char *data,
|
|
|
+ size_t dataLen)
|
|
|
+{
|
|
|
+ return mg_websocket_write_exec(conn, opcode, data, dataLen, 0);
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+mg_websocket_client_write(struct mg_connection *conn,
|
|
|
+ int opcode,
|
|
|
+ const char *data,
|
|
|
+ size_t dataLen)
|
|
|
+{
|
|
|
+ return mg_websocket_write_exec(conn, opcode, data, dataLen, 1);
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
handle_websocket_request(struct mg_connection *conn,
|
|
|
const char *path,
|