Sun, 27 Nov 2022 13:33:30 +0100
improve daemon startup
parent will wait until daemon is started and returns error code if startup failed
daemon startup log messages will be printed by parent
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 | } |