src/server/daemon/websocket.c

Wed, 05 Jun 2024 19:50:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 05 Jun 2024 19:50:44 +0200
changeset 537
ad44e72fbf50
parent 415
d938228c382e
permissions
-rw-r--r--

add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled

127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2016 Olaf Wintermann. All rights reserved.
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include <stdio.h>
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include <stdlib.h>
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include "websocket.h"
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 #include "../util/io.h"
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35 #include "../util/pblock.h"
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 #include "../util/util.h"
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 #include "../util/strbuf.h"
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
38 #include <cx/string.h>
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 #define WS_BUFFER_LEN 2048
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 NSAPI_PUBLIC int http_handle_websocket(Session *sn, Request *rq, WebSocket *websocket) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 char *connection = pblock_findkeyval(pb_key_connection, rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 char *upgrade = pblock_findval("upgrade", rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 char *origin = pblock_findval("origin", rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 char *wskey = pblock_findval("sec-websocket-key", rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 char *wsprot = pblock_findval("sec-websocket-protocol", rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 char *wsv = pblock_findval("sec-websocket-version", rq->headers);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 if(!connection || !upgrade) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 return REQ_NOACTION;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
54 if(cx_strcasecmp(cx_str(connection), (cxstring)CX_STR("upgrade"))) {
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 return REQ_NOACTION;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
57 if(cx_strcasecmp(cx_str(upgrade), (cxstring)CX_STR("websocket"))) {
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 return REQ_NOACTION;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
61 cxmutstr wsaccept = cx_strcat(2, cx_str(wskey), (cxstring)CX_STR("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 unsigned char hash[20];
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 SHA1((const unsigned char*)wsaccept.ptr, wsaccept.length, hash);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 char *websocket_accept = util_base64encode((char*)hash, 20);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 sbuf_t *response = sbuf_new(512);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
67 sbuf_append(response, (cxstring)CX_STR("HTTP/1.1 101 Switching Protocols\r\n"));
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
68 sbuf_append(response, (cxstring)CX_STR("Upgrade: websocket\r\n"));
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
69 sbuf_append(response, (cxstring)CX_STR("Connection: Upgrade\r\n"));
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
70 sbuf_append(response, (cxstring)CX_STR("Sec-WebSocket-Accept: "));
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 sbuf_puts(response, websocket_accept);
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 388
diff changeset
72 sbuf_append(response, (cxstring)CX_STR("\r\n\r\n"));
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 net_write(sn->csd, response->ptr, response->length);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 sbuf_free(response);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 free(websocket_accept);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 free(wsaccept.ptr);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 // start websocket I/O
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 WSParser *parser = websocket_parser(sn);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 WSFrame frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 int ret = REQ_PROCEED;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 char *inbuf = pool_malloc(sn->pool, WS_BUFFER_LEN);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 ssize_t r = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 while((r = net_read(sn->csd, inbuf, WS_BUFFER_LEN)) > 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 websocket_input(parser, inbuf, r);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 WSMessage *msg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 int error;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 while((msg = websocket_get_message(parser, &error)) != NULL) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 websocket->on_message(websocket, msg);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 if(error) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 log_ereport(LOG_FAILURE, "websocket protocol error");
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 break;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 return ret;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 WSParser* websocket_parser(Session *sn) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 WSParser *parser = pool_malloc(sn->pool, sizeof(WSParser));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 if(!parser) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 return NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 ZERO(parser, sizeof(WSParser));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 parser->pool = sn->pool;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 return parser;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 void websocket_input(WSParser *parser, const char *data, size_t length) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 parser->inbuf = data;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 parser->length = length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 parser->pos = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 WSMessage* websocket_get_message(WSParser *parser, int *error) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 WSFrame rframe;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 WSMessage *retmsg = NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 while(parser->pos < parser->length) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 const char *inbuf = parser->inbuf + parser->pos;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 size_t length = parser->length - parser->pos;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 if(parser->state == 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 WSFrame frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 ZERO(&frame, sizeof(WSFrame));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 /*
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 * small buffer for a websocket frame without payload data
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 * I know using so many buffers it not zero copy but
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 * it makes things a little bit easier :)
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 */
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 char frame_data[WS_FRAMEHEADER_BUFLEN];
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138 size_t flen = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 /*
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 * when the last call of websocket_get_message didn't completed
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 * a frame header, the tmpbuf contains the remaining bytes
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 * in this case we combine tmpbuf and inputbuf
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 */
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 if(parser->tmplen > 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 memcpy(parser->tmpbuf, frame_data, parser->tmplen);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 flen = parser->tmplen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 size_t cp_remaining = length < WS_FRAMEHEADER_BUFLEN-flen ?
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 length : WS_FRAMEHEADER_BUFLEN-flen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 memcpy(&frame_data[flen], inbuf, cp_remaining);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 flen += cp_remaining;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 // ready to parse the frame
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 ssize_t frame_hlen = websocket_get_frameheader(
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 &frame,
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 frame_data,
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 flen);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 if(frame_hlen == -1) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 // protocol error, abort
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 *error = 1;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 return NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 if(frame_hlen == 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 memcpy(parser->tmpbuf, frame_data, flen);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 inbuf += frame_hlen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 length -= frame_hlen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 parser->pos += frame_hlen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 // frame complete, create a message object
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 if(frame.payload_length > 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 WSMessage *msg = pool_malloc(parser->pool, sizeof(WSMessage));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 msg->data = pool_malloc(parser->pool, frame.payload_length);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 msg->length = frame.payload_length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 msg->next = NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 msg->type = frame.opcode;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 if(frame.payload_length >= length) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 // message complete
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 memcpy(msg->data, inbuf, frame.payload_length);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 parser->pos += frame.payload_length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 rframe = frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 retmsg = msg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 break;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 memcpy(msg->data, inbuf, length);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 parser->state = 1;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 parser->current = msg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 parser->cur_plen = length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 parser->frame = frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 return NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 WSMessage *msg = parser->current;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 if(msg->length >= parser->cur_plen + length) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 // still incomplete message
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 memcpy(msg->data + parser->cur_plen, inbuf, length);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 parser->cur_plen += length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 return NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 size_t cplen = msg->length - parser->cur_plen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 memcpy(msg->data + parser->cur_plen, inbuf, cplen);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 parser->pos += cplen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 parser->state = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 parser->current = NULL;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 rframe = parser->frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 retmsg = msg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 break;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 if(retmsg && rframe.mask) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 websocket_mask_data(retmsg->data, retmsg->length, rframe.masking_key);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 return retmsg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 ssize_t websocket_get_frameheader(WSFrame *frame, const char *buf, size_t len) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 if(len < 2) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 return 0; // too small for anything
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 /*
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 printf("websocket_get_frameheader: ");
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 for(int i=0;i<len;i++) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 printf("%x ", buf[i]);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 if(len > 15) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 break;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 printf("\n");
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 */
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 size_t msglen = 2; // minimal length
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 uint8_t fin = (buf[0] & 0x80) != 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 uint8_t opcode = buf[0] & 0xf;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 uint8_t mask = (buf[1] & 0x80) != 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 uint8_t payload_len = buf[1] & 0x7f;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 uint64_t payload_length = payload_len;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 if(payload_len == 126) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 msglen += 2;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 if(len < msglen) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 return 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 payload_length = *((uint16_t*)(buf+2));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257 } else if(payload_len == 127) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 msglen += 8;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 if(len < msglen) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 return 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 payload_length = *((uint64_t*)(buf+2));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 } else if(payload_len > 127) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 return -1;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
266
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 uint32_t masking_key = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 if(mask) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 msglen += 4;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 if(len < msglen) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 return 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 masking_key = *((uint32_t*)(buf+msglen-4));
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 frame->header_complete = TRUE;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277 frame->fin = fin;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 frame->opcode = opcode;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 frame->mask = mask;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 frame->masking_key = masking_key;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 frame->payload_length = payload_length;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 return msglen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 void websocket_mask_data(char *buf, size_t len, uint32_t mask) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 size_t m = len % 4;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 size_t alen = (len - m) / 4;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 uint32_t *data = (uint32_t*)buf;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 for(int i=0;i<alen;i++) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 data[i] = data[i] ^ mask;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 int j = 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 char *cmask = (char*)&mask;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 for(int i=len-m;i<len;i++) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 buf[i] = buf[i] ^ cmask[j];
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 j++;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 /* ------------------------------ public API ------------------------------*/
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 NSAPI_PUBLIC int websocket_send_text(SYS_NETFD csd, char *msg, size_t len) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 char frame[WS_FRAMEHEADER_BUFLEN];
388
30d29ef5b79a change uid before most of the config is loaded
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 162
diff changeset
307 frame[0] = (char)129; // 0b10000001
127
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 size_t hlen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 if(len < 126) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 frame[1] = (char)len;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 hlen = 2;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 } else if(len < 65536) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 frame[1] = 126;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 uint16_t plen = htons(len);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 memcpy(frame + 2, &plen, 2);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 hlen = 4;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 frame[1] = 127;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 // TODO
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 hlen = 10;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 struct iovec iov[2];
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 iov[0].iov_base = frame;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 iov[0].iov_len = hlen;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 iov[1].iov_base = msg;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328 iov[1].iov_len = len;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 ssize_t w = net_writev(csd, iov, 2);
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 if(w > 0) {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 return 0;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 } else {
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 return 1;
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 }
84e206063b64 adds minimal websocket implementation
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336 }

mercurial