src/server/daemon/websocket.c

Wed, 27 Nov 2024 23:00:07 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 27 Nov 2024 23:00:07 +0100
changeset 563
6ca97c99173e
parent 415
d938228c382e
permissions
-rw-r--r--

add TODO to use a future ucx feature

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