2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #include "private-libwebsockets.h"
24 const struct lws_tokens lws_tokens[WSI_TOKEN_COUNT] = {
26 /* win32 can't do C99 */
28 /* [WSI_TOKEN_GET_URI] = */{ "GET ", 4 },
29 /* [WSI_TOKEN_HOST] = */{ "Host:", 5 },
30 /* [WSI_TOKEN_CONNECTION] = */{ "Connection:", 11 },
31 /* [WSI_TOKEN_KEY1] = */{ "Sec-WebSocket-Key1:", 19 },
32 /* [WSI_TOKEN_KEY2] = */{ "Sec-WebSocket-Key2:", 19 },
33 /* [WSI_TOKEN_PROTOCOL] = */{ "Sec-WebSocket-Protocol:", 23 },
34 /* [WSI_TOKEN_UPGRADE] = */{ "Upgrade:", 8 },
35 /* [WSI_TOKEN_ORIGIN] = */{ "Origin:", 7 },
36 /* [WSI_TOKEN_DRAFT] = */{ "Sec-WebSocket-Draft:", 20 },
37 /* [WSI_TOKEN_CHALLENGE] = */{ "\x0d\x0a", 2 },
39 /* [WSI_TOKEN_KEY] = */{ "Sec-WebSocket-Key:", 18 },
40 /* [WSI_TOKEN_VERSION] = */{ "Sec-WebSocket-Version:", 22 },
41 /* [WSI_TOKEN_SWORIGIN]= */{ "Sec-WebSocket-Origin:", 21 },
43 /* [WSI_TOKEN_EXTENSIONS] = */{ "Sec-WebSocket-Extensions:", 25 },
45 /* [WSI_TOKEN_ACCEPT] = */{ "Sec-WebSocket-Accept:", 21 },
46 /* [WSI_TOKEN_NONCE] = */{ "Sec-WebSocket-Nonce:", 20 },
47 /* [WSI_TOKEN_HTTP] = */{ "HTTP/1.1 ", 9 },
48 /* [WSI_TOKEN_MUXURL] = */{ "", -1 },
52 int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
56 switch (wsi->parser_state) {
57 case WSI_TOKEN_GET_URI:
59 case WSI_TOKEN_CONNECTION:
62 case WSI_TOKEN_PROTOCOL:
63 case WSI_TOKEN_UPGRADE:
64 case WSI_TOKEN_ORIGIN:
65 case WSI_TOKEN_SWORIGIN:
67 case WSI_TOKEN_CHALLENGE:
69 case WSI_TOKEN_VERSION:
70 case WSI_TOKEN_ACCEPT:
72 case WSI_TOKEN_EXTENSIONS:
74 case WSI_TOKEN_MUXURL:
76 debug("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c);
78 /* collect into malloc'd buffers */
79 /* optional space swallow */
80 if (!wsi->utf8_token[wsi->parser_state].token_len && c == ' ')
83 /* special case space terminator for get-uri */
84 if (wsi->parser_state == WSI_TOKEN_GET_URI && c == ' ') {
85 wsi->utf8_token[wsi->parser_state].token[
86 wsi->utf8_token[wsi->parser_state].token_len] = '\0';
87 wsi->parser_state = WSI_TOKEN_SKIPPING;
91 /* allocate appropriate memory */
92 if (wsi->utf8_token[wsi->parser_state].token_len ==
93 wsi->current_alloc_len - 1) {
95 wsi->current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
96 if (wsi->current_alloc_len >= LWS_MAX_HEADER_LEN) {
97 /* it's waaay to much payload, fail it */
98 strcpy(wsi->utf8_token[wsi->parser_state].token,
99 "!!! Length exceeded maximum supported !!!");
100 wsi->parser_state = WSI_TOKEN_SKIPPING;
103 wsi->utf8_token[wsi->parser_state].token =
104 realloc(wsi->utf8_token[wsi->parser_state].token,
105 wsi->current_alloc_len);
109 if (wsi->parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
110 wsi->utf8_token[wsi->parser_state].token[
111 wsi->utf8_token[wsi->parser_state].token_len] = '\0';
112 wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
113 fprintf(stderr, "*\n");
117 wsi->utf8_token[wsi->parser_state].token[
118 wsi->utf8_token[wsi->parser_state].token_len++] = c;
120 /* per-protocol end of headers management */
122 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
125 /* -76 has no version header ... server */
126 if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
127 wsi->mode != LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY &&
128 wsi->utf8_token[wsi->parser_state].token_len != 8)
131 /* -76 has no version header ... client */
132 if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
133 wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY &&
134 wsi->utf8_token[wsi->parser_state].token_len != 16)
137 /* <= 03 has old handshake with version header needs 8 bytes */
138 if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
139 atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) < 4 &&
140 wsi->utf8_token[wsi->parser_state].token_len != 8)
143 /* no payload challenge in 01 + */
145 if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
146 atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) > 0) {
147 wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len = 0;
148 free(wsi->utf8_token[WSI_TOKEN_CHALLENGE].token);
149 wsi->utf8_token[WSI_TOKEN_CHALLENGE].token = NULL;
152 /* For any supported protocol we have enough payload */
154 debug("Setting WSI_PARSING_COMPLETE\n");
155 wsi->parser_state = WSI_PARSING_COMPLETE;
158 case WSI_INIT_TOKEN_MUXURL:
159 wsi->parser_state = WSI_TOKEN_MUXURL;
160 wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
162 wsi->utf8_token[wsi->parser_state].token =
163 malloc(wsi->current_alloc_len);
164 wsi->utf8_token[wsi->parser_state].token_len = 0;
167 /* collecting and checking a name part */
168 case WSI_TOKEN_NAME_PART:
169 debug("WSI_TOKEN_NAME_PART '%c'\n", c);
171 if (wsi->name_buffer_pos == sizeof(wsi->name_buffer) - 1) {
172 /* name bigger than we can handle, skip until next */
173 wsi->parser_state = WSI_TOKEN_SKIPPING;
176 wsi->name_buffer[wsi->name_buffer_pos++] = c;
177 wsi->name_buffer[wsi->name_buffer_pos] = '\0';
179 for (n = 0; n < WSI_TOKEN_COUNT; n++) {
180 if (wsi->name_buffer_pos != lws_tokens[n].token_len)
182 if (strcmp(lws_tokens[n].token, wsi->name_buffer))
184 debug("known hdr '%s'\n", wsi->name_buffer);
185 wsi->parser_state = WSI_TOKEN_GET_URI + n;
186 wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
188 wsi->utf8_token[wsi->parser_state].token =
189 malloc(wsi->current_alloc_len);
190 wsi->utf8_token[wsi->parser_state].token_len = 0;
194 /* colon delimiter means we just don't know this name */
196 if (wsi->parser_state == WSI_TOKEN_NAME_PART && c == ':') {
197 debug("skipping unknown header '%s'\n",
199 wsi->parser_state = WSI_TOKEN_SKIPPING;
203 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
206 /* don't look for payload when it can just be http headers */
208 if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len) {
209 /* they're HTTP headers, not websocket upgrade! */
210 debug("Setting WSI_PARSING_COMPLETE "
211 "from http headers\n");
212 wsi->parser_state = WSI_PARSING_COMPLETE;
215 /* 04 version has no packet content after end of hdrs */
217 if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
218 atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) >= 4) {
219 debug("04 header completed\n");
220 wsi->parser_state = WSI_PARSING_COMPLETE;
221 wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len = 0;
222 free(wsi->utf8_token[WSI_TOKEN_CHALLENGE].token);
223 wsi->utf8_token[WSI_TOKEN_CHALLENGE].token = NULL;
228 if (wsi->ietf_spec_revision >= 4) {
229 debug("04 header completed\n");
230 wsi->parser_state = WSI_PARSING_COMPLETE;
235 /* skipping arg part of a name we didn't recognize */
236 case WSI_TOKEN_SKIPPING:
237 debug("WSI_TOKEN_SKIPPING '%c'\n", c);
239 wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
241 case WSI_TOKEN_SKIPPING_SAW_CR:
242 debug("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
244 wsi->parser_state = WSI_TOKEN_NAME_PART;
246 wsi->parser_state = WSI_TOKEN_SKIPPING;
247 wsi->name_buffer_pos = 0;
249 /* we're done, ignore anything else */
250 case WSI_PARSING_COMPLETE:
251 debug("WSI_PARSING_COMPLETE '%c'\n", c);
254 default: /* keep gcc happy */
262 xor_no_mask(struct libwebsocket *wsi, unsigned char c)
268 xor_mask_04(struct libwebsocket *wsi, unsigned char c)
270 c ^= wsi->masking_key_04[wsi->frame_mask_index++];
271 if (wsi->frame_mask_index == 20)
272 wsi->frame_mask_index = 0;
278 xor_mask_05(struct libwebsocket *wsi, unsigned char c)
280 return c ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
286 libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
289 unsigned char buf[20 + 4];
290 struct lws_tokens eff_buf;
294 // fprintf(stderr, "RX: %02X ", c);
296 switch (wsi->lws_rx_parse_state) {
299 switch (wsi->ietf_spec_revision) {
300 /* Firefox 4.0b6 likes this as of 30 Oct 2010 */
303 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
305 wsi->lws_rx_parse_state =
306 LWS_RXPS_EAT_UNTIL_76_FF;
307 wsi->rx_user_buffer_head = 0;
313 wsi->all_zero_nonce = 1;
314 wsi->frame_masking_nonce_04[0] = c;
316 wsi->all_zero_nonce = 0;
317 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_1;
323 * no prepended frame key any more
325 wsi->all_zero_nonce = 1;
329 fprintf(stderr, "libwebsocket_rx_sm doesn't know "
330 "about spec version %d\n", wsi->ietf_spec_revision);
334 case LWS_RXPS_04_MASK_NONCE_1:
335 wsi->frame_masking_nonce_04[1] = c;
337 wsi->all_zero_nonce = 0;
338 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
340 case LWS_RXPS_04_MASK_NONCE_2:
341 wsi->frame_masking_nonce_04[2] = c;
343 wsi->all_zero_nonce = 0;
344 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
346 case LWS_RXPS_04_MASK_NONCE_3:
347 wsi->frame_masking_nonce_04[3] = c;
349 wsi->all_zero_nonce = 0;
351 if (wsi->protocol->owning_server->options &
352 LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK)
355 if (wsi->ietf_spec_revision > 4)
359 * we are able to compute the frame key now
360 * it's a SHA1 of ( frame nonce we were just sent, concatenated
361 * with the connection masking key we computed at handshake
362 * time ) -- yeah every frame from the client invokes a SHA1
363 * for no real reason so much for lightweight.
366 buf[0] = wsi->frame_masking_nonce_04[0];
367 buf[1] = wsi->frame_masking_nonce_04[1];
368 buf[2] = wsi->frame_masking_nonce_04[2];
369 buf[3] = wsi->frame_masking_nonce_04[3];
371 memcpy(buf + 4, wsi->masking_key_04, 20);
374 * wsi->frame_mask_04 will be our recirculating 20-byte XOR key
378 SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
383 * start from the zero'th byte in the XOR key buffer since
384 * this is the start of a frame with a new key
387 wsi->frame_mask_index = 0;
390 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
394 * 04 logical framing from the spec (all this is masked when incoming
395 * and has to be unmasked)
397 * We ignore the possibility of extension data because we don't
398 * negotiate any extensions at the moment.
401 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
402 * +-+-+-+-+-------+-+-------------+-------------------------------+
403 * |F|R|R|R| opcode|R| Payload len | Extended payload length |
404 * |I|S|S|S| (4) |S| (7) | (16/63) |
405 * |N|V|V|V| |V| | (if payload len==126/127) |
407 * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
408 * | Extended payload length continued, if payload len == 127 |
409 * + - - - - - - - - - - - - - - - +-------------------------------+
410 * | | Extension data |
411 * +-------------------------------+ - - - - - - - - - - - - - - - +
413 * +---------------------------------------------------------------+
414 * : Application data :
415 * +---------------------------------------------------------------+
417 * We pass payload through to userland as soon as we get it, ignoring
418 * FIN. It's up to userland to buffer it up if it wants to see a
419 * whole unfragmented block of the original size (which may be up to
423 case LWS_RXPS_04_FRAME_HDR_1:
427 * 04 spec defines the opcode like this: (1, 2, and 3 are
428 * "control frame" opcodes which may not be fragmented or
429 * have size larger than 126)
432 * %x0 ; continuation frame
433 * / %x1 ; connection close
437 * / %x5 ; binary frame
443 if (wsi->ietf_spec_revision < 7)
444 c = wsi->xor_mask(wsi, c);
448 "Frame has unknown extension bits set 1 %02X\n", c);
450 /* translate all incoming opcodes into v7+ map */
451 if (wsi->ietf_spec_revision < 7)
453 case LWS_WS_OPCODE_04__CONTINUATION:
454 wsi->opcode = LWS_WS_OPCODE_07__CONTINUATION;
456 case LWS_WS_OPCODE_04__CLOSE:
457 wsi->opcode = LWS_WS_OPCODE_07__CLOSE;
459 case LWS_WS_OPCODE_04__PING:
460 wsi->opcode = LWS_WS_OPCODE_07__PING;
462 case LWS_WS_OPCODE_04__PONG:
463 wsi->opcode = LWS_WS_OPCODE_07__PONG;
465 case LWS_WS_OPCODE_04__TEXT_FRAME:
466 wsi->opcode = LWS_WS_OPCODE_07__TEXT_FRAME;
468 case LWS_WS_OPCODE_04__BINARY_FRAME:
469 wsi->opcode = LWS_WS_OPCODE_07__BINARY_FRAME;
472 fprintf(stderr, "reserved opcodes not "
473 "usable pre v7 protocol\n");
477 wsi->opcode = c & 0xf;
479 wsi->final = !!((c >> 7) & 1);
481 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
484 case LWS_RXPS_04_FRAME_HDR_LEN:
486 if (wsi->ietf_spec_revision < 7)
487 c = wsi->xor_mask(wsi, c);
489 if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
490 fprintf(stderr, "Frame has extensions "
491 "set illegally 2\n");
492 /* kill the connection */
496 wsi->this_frame_masked = !!(c & 0x80);
500 /* control frames are not allowed to have big lengths */
502 goto illegal_ctl_length;
504 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
507 /* control frames are not allowed to have big lengths */
509 goto illegal_ctl_length;
511 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
514 wsi->rx_packet_length = c & 0x7f;
515 if (wsi->this_frame_masked)
516 wsi->lws_rx_parse_state =
517 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
519 wsi->lws_rx_parse_state =
520 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
525 case LWS_RXPS_04_FRAME_HDR_LEN16_2:
526 if (wsi->ietf_spec_revision < 7)
527 c = wsi->xor_mask(wsi, c);
529 wsi->rx_packet_length = c << 8;
530 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
533 case LWS_RXPS_04_FRAME_HDR_LEN16_1:
534 if (wsi->ietf_spec_revision < 7)
535 c = wsi->xor_mask(wsi, c);
537 wsi->rx_packet_length |= c;
538 if (wsi->this_frame_masked)
539 wsi->lws_rx_parse_state =
540 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
542 wsi->lws_rx_parse_state =
543 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
546 case LWS_RXPS_04_FRAME_HDR_LEN64_8:
547 if (wsi->ietf_spec_revision < 7)
548 c = wsi->xor_mask(wsi, c);
550 fprintf(stderr, "b63 of length must be zero\n");
551 /* kill the connection */
555 wsi->rx_packet_length = ((size_t)c) << 56;
557 wsi->rx_packet_length = 0;
559 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
562 case LWS_RXPS_04_FRAME_HDR_LEN64_7:
563 if (wsi->ietf_spec_revision < 7)
564 c = wsi->xor_mask(wsi, c);
566 wsi->rx_packet_length |= ((size_t)c) << 48;
568 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
571 case LWS_RXPS_04_FRAME_HDR_LEN64_6:
572 if (wsi->ietf_spec_revision < 7)
573 c = wsi->xor_mask(wsi, c);
575 wsi->rx_packet_length |= ((size_t)c) << 40;
577 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
580 case LWS_RXPS_04_FRAME_HDR_LEN64_5:
581 if (wsi->ietf_spec_revision < 7)
582 c = wsi->xor_mask(wsi, c);
584 wsi->rx_packet_length |= ((size_t)c) << 32;
586 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
589 case LWS_RXPS_04_FRAME_HDR_LEN64_4:
590 if (wsi->ietf_spec_revision < 7)
591 c = wsi->xor_mask(wsi, c);
592 wsi->rx_packet_length |= ((size_t)c) << 24;
593 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
596 case LWS_RXPS_04_FRAME_HDR_LEN64_3:
597 if (wsi->ietf_spec_revision < 7)
598 c = wsi->xor_mask(wsi, c);
599 wsi->rx_packet_length |= ((size_t)c) << 16;
600 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
603 case LWS_RXPS_04_FRAME_HDR_LEN64_2:
604 if (wsi->ietf_spec_revision < 7)
605 c = wsi->xor_mask(wsi, c);
606 wsi->rx_packet_length |= ((size_t)c) << 8;
607 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
610 case LWS_RXPS_04_FRAME_HDR_LEN64_1:
611 if (wsi->ietf_spec_revision < 7)
612 c = wsi->xor_mask(wsi, c);
613 wsi->rx_packet_length |= ((size_t)c);
614 if (wsi->this_frame_masked)
615 wsi->lws_rx_parse_state =
616 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
618 wsi->lws_rx_parse_state =
619 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
622 case LWS_RXPS_EAT_UNTIL_76_FF:
624 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
627 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
628 (wsi->rx_user_buffer_head++)] = c;
630 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
633 if (wsi->protocol->callback)
634 wsi->protocol->callback(wsi->protocol->owning_server,
635 wsi, LWS_CALLBACK_RECEIVE,
637 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
638 wsi->rx_user_buffer_head);
639 wsi->rx_user_buffer_head = 0;
641 case LWS_RXPS_SEEN_76_FF:
645 debug("Seen that client is requesting "
646 "a v76 close, sending ack\n");
649 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
651 fprintf(stderr, "ERROR writing to socket");
654 debug(" v76 close ack sent, server closing skt\n");
655 /* returning < 0 will get it closed in parent */
658 case LWS_RXPS_PULLING_76_LENGTH:
662 case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
663 wsi->frame_masking_nonce_04[0] = c;
665 wsi->all_zero_nonce = 0;
666 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
669 case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
670 wsi->frame_masking_nonce_04[1] = c;
672 wsi->all_zero_nonce = 0;
673 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
676 case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
677 wsi->frame_masking_nonce_04[2] = c;
679 wsi->all_zero_nonce = 0;
680 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
683 case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
684 wsi->frame_masking_nonce_04[3] = c;
686 wsi->all_zero_nonce = 0;
687 wsi->lws_rx_parse_state =
688 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
689 wsi->frame_mask_index = 0;
693 case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
694 if (wsi->ietf_spec_revision < 4 || (wsi->all_zero_nonce && wsi->ietf_spec_revision >= 5))
695 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
696 (wsi->rx_user_buffer_head++)] = c;
698 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
699 (wsi->rx_user_buffer_head++)] =
700 wsi->xor_mask(wsi, c);
702 if (--wsi->rx_packet_length == 0) {
703 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
706 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
710 * is this frame a control packet we should take care of at this
711 * layer? If so service it and hide it from the user callback
714 debug("spill on %s\n", wsi->protocol->name);
716 switch (wsi->opcode) {
717 case LWS_WS_OPCODE_07__CLOSE:
718 /* is this an acknowledgement of our close? */
719 if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
721 * fine he has told us he is closing too, let's
724 fprintf(stderr, "seen client close ack\n");
727 fprintf(stderr, "server sees client close packet\n");
728 /* parrot the close packet payload back */
729 n = libwebsocket_write(wsi, (unsigned char *)
730 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
731 wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
732 wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
733 /* close the connection */
736 case LWS_WS_OPCODE_07__PING:
737 /* parrot the ping packet payload back as a pong */
738 n = libwebsocket_write(wsi, (unsigned char *)
739 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
740 wsi->rx_user_buffer_head, LWS_WRITE_PONG);
741 /* ... then just drop it */
742 wsi->rx_user_buffer_head = 0;
745 case LWS_WS_OPCODE_07__PONG:
746 /* keep the statistics... */
747 wsi->pings_vs_pongs--;
748 /* ... then just drop it */
749 wsi->rx_user_buffer_head = 0;
752 case LWS_WS_OPCODE_07__TEXT_FRAME:
753 case LWS_WS_OPCODE_07__BINARY_FRAME:
758 debug("passing opcode %x up to exts\n", wsi->opcode);
761 * It's something special we can't understand here.
762 * Pass the payload up to the extension's parsing
766 eff_buf.token = &wsi->rx_user_buffer[
767 LWS_SEND_BUFFER_PRE_PADDING];
768 eff_buf.token_len = wsi->rx_user_buffer_head;
771 for (n = 0; n < wsi->count_active_extensions; n++) {
772 m = wsi->active_extensions[n]->callback(
773 wsi->protocol->owning_server,
774 wsi->active_extensions[n], wsi,
775 LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
776 wsi->active_extensions_user[n],
783 fprintf(stderr, "Unhandled extended opcode "
784 "0x%x - ignoring frame\n", wsi->opcode);
786 wsi->rx_user_buffer_head = 0;
791 * No it's real payload, pass it up to the user callback.
792 * It's nicely buffered with the pre-padding taken care of
793 * so it can be sent straight out again using libwebsocket_write
796 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
797 wsi->rx_user_buffer_head] = '\0';
799 if (wsi->protocol->callback)
800 wsi->protocol->callback(wsi->protocol->owning_server,
801 wsi, LWS_CALLBACK_RECEIVE,
803 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
804 wsi->rx_user_buffer_head);
806 fprintf(stderr, "No callback on payload spill!\n");
808 wsi->rx_user_buffer_head = 0;
816 fprintf(stderr, "Control frame asking for "
817 "extended length is illegal\n");
818 /* kill the connection */
823 int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
826 unsigned char buf[20 + 4];
827 int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
829 struct lws_tokens eff_buf;
832 debug(" CRX: %02X %d\n", c, wsi->lws_rx_parse_state);
834 switch (wsi->lws_rx_parse_state) {
837 switch (wsi->ietf_spec_revision) {
838 /* Firefox 4.0b6 likes this as of 30 Oct */
841 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
843 wsi->lws_rx_parse_state =
844 LWS_RXPS_EAT_UNTIL_76_FF;
845 wsi->rx_user_buffer_head = 0;
855 * 04 logical framing from the spec (all this is masked when
856 * incoming and has to be unmasked)
858 * We ignore the possibility of extension data because we don't
859 * negotiate any extensions at the moment.
862 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
863 * +-+-+-+-+-------+-+-------------+-------------------------------+
864 * |F|R|R|R| opcode|R| Payload len | Extended payload length |
865 * |I|S|S|S| (4) |S| (7) | (16/63) |
866 * |N|V|V|V| |V| | (if payload len==126/127) |
868 * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
869 * | Extended payload length continued, if payload len == 127 |
870 * + - - - - - - - - - - - - - - - +-------------------------------+
871 * | | Extension data |
872 * +-------------------------------+ - - - - - - - - - - - - - - - +
874 * +---------------------------------------------------------------+
875 * : Application data :
876 * +---------------------------------------------------------------+
878 * We pass payload through to userland as soon as we get it, ignoring
879 * FIN. It's up to userland to buffer it up if it wants to see a
880 * whole unfragmented block of the original size (which may be up to
883 * Notice in v7 RSV4 is set to indicate 32-bit frame key is coming in
884 * after length, unlike extension data which is now deprecated, this
885 * does not impact the payload length calculation.
889 * 04 spec defines the opcode like this: (1, 2, and 3 are
890 * "control frame" opcodes which may not be fragmented or
891 * have size larger than 126)
894 * %x0 ; continuation frame
895 * / %x1 ; connection close
899 * / %x5 ; binary frame
906 fprintf(stderr, "Frame has unknown extension "
907 "bits set on first framing byte %02X\n", c);
909 if (wsi->ietf_spec_revision < 7)
911 case LWS_WS_OPCODE_04__CONTINUATION:
912 wsi->opcode = LWS_WS_OPCODE_07__CONTINUATION;
914 case LWS_WS_OPCODE_04__CLOSE:
915 wsi->opcode = LWS_WS_OPCODE_07__CLOSE;
917 case LWS_WS_OPCODE_04__PING:
918 wsi->opcode = LWS_WS_OPCODE_07__PING;
920 case LWS_WS_OPCODE_04__PONG:
921 wsi->opcode = LWS_WS_OPCODE_07__PONG;
923 case LWS_WS_OPCODE_04__TEXT_FRAME:
924 wsi->opcode = LWS_WS_OPCODE_07__TEXT_FRAME;
926 case LWS_WS_OPCODE_04__BINARY_FRAME:
927 wsi->opcode = LWS_WS_OPCODE_07__BINARY_FRAME;
930 fprintf(stderr, "reserved opcodes not "
931 "usable pre v7 protocol\n");
935 wsi->opcode = c & 0xf;
937 wsi->final = !!((c >> 7) & 1);
939 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
943 fprintf(stderr, "client_rx_sm doesn't know how "
944 "to handle spec version %02d\n",
945 wsi->ietf_spec_revision);
951 case LWS_RXPS_04_FRAME_HDR_LEN:
953 if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
955 "Frame has extensions set illegally 4\n");
956 /* kill the connection */
960 wsi->this_frame_masked = !!(c & 0x80);
964 /* control frames are not allowed to have big lengths */
966 goto illegal_ctl_length;
967 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
970 /* control frames are not allowed to have big lengths */
972 goto illegal_ctl_length;
973 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
976 wsi->rx_packet_length = c;
977 if (wsi->this_frame_masked)
978 wsi->lws_rx_parse_state =
979 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
982 wsi->lws_rx_parse_state =
983 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
985 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
993 case LWS_RXPS_04_FRAME_HDR_LEN16_2:
994 wsi->rx_packet_length = c << 8;
995 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
998 case LWS_RXPS_04_FRAME_HDR_LEN16_1:
999 wsi->rx_packet_length |= c;
1000 if (wsi->this_frame_masked)
1001 wsi->lws_rx_parse_state =
1002 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1004 if (wsi->rx_packet_length)
1005 wsi->lws_rx_parse_state =
1006 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1008 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1014 case LWS_RXPS_04_FRAME_HDR_LEN64_8:
1016 fprintf(stderr, "b63 of length must be zero\n");
1017 /* kill the connection */
1020 #if defined __LP64__
1021 wsi->rx_packet_length = ((size_t)c) << 56;
1023 wsi->rx_packet_length = 0;
1025 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
1028 case LWS_RXPS_04_FRAME_HDR_LEN64_7:
1029 #if defined __LP64__
1030 wsi->rx_packet_length |= ((size_t)c) << 48;
1032 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
1035 case LWS_RXPS_04_FRAME_HDR_LEN64_6:
1036 #if defined __LP64__
1037 wsi->rx_packet_length |= ((size_t)c) << 40;
1039 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
1042 case LWS_RXPS_04_FRAME_HDR_LEN64_5:
1043 #if defined __LP64__
1044 wsi->rx_packet_length |= ((size_t)c) << 32;
1046 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
1049 case LWS_RXPS_04_FRAME_HDR_LEN64_4:
1050 wsi->rx_packet_length |= ((size_t)c) << 24;
1051 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
1054 case LWS_RXPS_04_FRAME_HDR_LEN64_3:
1055 wsi->rx_packet_length |= ((size_t)c) << 16;
1056 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
1059 case LWS_RXPS_04_FRAME_HDR_LEN64_2:
1060 wsi->rx_packet_length |= ((size_t)c) << 8;
1061 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
1064 case LWS_RXPS_04_FRAME_HDR_LEN64_1:
1065 wsi->rx_packet_length |= (size_t)c;
1066 if (wsi->this_frame_masked)
1067 wsi->lws_rx_parse_state =
1068 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1070 if (wsi->rx_packet_length)
1071 wsi->lws_rx_parse_state =
1072 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1074 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1080 case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
1081 wsi->frame_masking_nonce_04[0] = c;
1083 wsi->all_zero_nonce = 0;
1084 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
1087 case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
1088 wsi->frame_masking_nonce_04[1] = c;
1090 wsi->all_zero_nonce = 0;
1091 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
1094 case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
1095 wsi->frame_masking_nonce_04[2] = c;
1097 wsi->all_zero_nonce = 0;
1098 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
1101 case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
1102 wsi->frame_masking_nonce_04[3] = c;
1104 wsi->all_zero_nonce = 0;
1106 if (wsi->rx_packet_length)
1107 wsi->lws_rx_parse_state =
1108 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1110 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1115 case LWS_RXPS_EAT_UNTIL_76_FF:
1117 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1120 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
1121 (wsi->rx_user_buffer_head++)] = c;
1123 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
1126 if (wsi->protocol->callback)
1127 wsi->protocol->callback(wsi->protocol->owning_server,
1129 LWS_CALLBACK_CLIENT_RECEIVE,
1131 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1132 wsi->rx_user_buffer_head);
1133 wsi->rx_user_buffer_head = 0;
1135 case LWS_RXPS_SEEN_76_FF:
1139 debug("Seen that client is requesting "
1140 "a v76 close, sending ack\n");
1143 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
1145 fprintf(stderr, "ERROR writing to socket");
1148 debug(" v76 close ack sent, server closing skt\n");
1149 /* returning < 0 will get it closed in parent */
1152 case LWS_RXPS_PULLING_76_LENGTH:
1155 case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
1156 if ((!wsi->this_frame_masked) || wsi->all_zero_nonce)
1157 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
1158 (wsi->rx_user_buffer_head++)] = c;
1160 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
1161 (wsi->rx_user_buffer_head++)] =
1162 wsi->xor_mask(wsi, c);
1164 if (--wsi->rx_packet_length == 0) {
1165 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1168 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
1175 * is this frame a control packet we should take care of at this
1176 * layer? If so service it and hide it from the user callback
1179 switch (wsi->opcode) {
1180 case LWS_WS_OPCODE_07__CLOSE:
1181 /* is this an acknowledgement of our close? */
1182 if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
1184 * fine he has told us he is closing too, let's
1187 fprintf(stderr, "seen server's close ack\n");
1190 fprintf(stderr, "client sees server close packet len = %d\n", wsi->rx_user_buffer_head);
1191 /* parrot the close packet payload back */
1192 n = libwebsocket_write(wsi, (unsigned char *)
1193 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1194 wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
1195 fprintf(stderr, "client writing close ack returned %d\n", n);
1196 wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
1197 /* close the connection */
1200 case LWS_WS_OPCODE_07__PING:
1201 /* parrot the ping packet payload back as a pong*/
1202 n = libwebsocket_write(wsi, (unsigned char *)
1203 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1204 wsi->rx_user_buffer_head, LWS_WRITE_PONG);
1208 case LWS_WS_OPCODE_07__PONG:
1209 /* keep the statistics... */
1210 wsi->pings_vs_pongs--;
1213 callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
1216 case LWS_WS_OPCODE_07__CONTINUATION:
1217 case LWS_WS_OPCODE_07__TEXT_FRAME:
1218 case LWS_WS_OPCODE_07__BINARY_FRAME:
1223 fprintf(stderr, "Reserved opcode 0x%2X\n", wsi->opcode);
1225 * It's something special we can't understand here.
1226 * Pass the payload up to the extension's parsing
1230 eff_buf.token = &wsi->rx_user_buffer[
1231 LWS_SEND_BUFFER_PRE_PADDING];
1232 eff_buf.token_len = wsi->rx_user_buffer_head;
1234 for (n = 0; n < wsi->count_active_extensions; n++) {
1235 m = wsi->active_extensions[n]->callback(
1236 wsi->protocol->owning_server,
1237 wsi->active_extensions[n], wsi,
1238 LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
1239 wsi->active_extensions_user[n],
1246 fprintf(stderr, "Unhandled extended opcode "
1247 "0x%x - ignoring frame\n", wsi->opcode);
1248 wsi->rx_user_buffer_head = 0;
1257 * No it's real payload, pass it up to the user callback.
1258 * It's nicely buffered with the pre-padding taken care of
1259 * so it can be sent straight out again using libwebsocket_write
1262 if (!handled && wsi->protocol->callback)
1263 wsi->protocol->callback(wsi->protocol->owning_server,
1264 wsi, callback_action,
1266 &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1267 wsi->rx_user_buffer_head);
1268 wsi->rx_user_buffer_head = 0;
1271 fprintf(stderr, "client rx illegal state\n");
1279 fprintf(stderr, "Control frame asking for "
1280 "extended length is illegal\n");
1281 /* kill the connection */
1288 int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
1289 unsigned char *buf, size_t len)
1294 fprintf(stderr, "received %d byte packet\n", (int)len);
1295 for (n = 0; n < len; n++)
1296 fprintf(stderr, "%02X ", buf[n]);
1297 fprintf(stderr, "\n");
1300 /* let the rx protocol state machine have as much as it needs */
1304 if (libwebsocket_rx_sm(wsi, buf[n++]) < 0)
1312 libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
1317 /* fetch the per-frame nonce */
1319 n = libwebsockets_get_random(wsi->protocol->owning_server,
1320 wsi->frame_masking_nonce_04, 4);
1322 fprintf(stderr, "Unable to read from random device %s %d\n",
1323 SYSTEM_RANDOM_FILEPATH, n);
1327 /* start masking from first byte of masking key buffer */
1328 wsi->frame_mask_index = 0;
1330 if (wsi->ietf_spec_revision != 4)
1333 /* 04 only does SHA-1 more complex key */
1336 * the frame key is the frame nonce (4 bytes) followed by the
1337 * connection masking key, hashed by SHA1
1340 memcpy(buf, wsi->frame_masking_nonce_04, 4);
1342 memcpy(buf + 4, wsi->masking_key_04, 20);
1344 /* concatenate the nonce with the connection key then hash it */
1346 SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
1351 void lws_stderr_hexdump(unsigned char *buf, size_t len)
1357 fprintf(stderr, "\n");
1359 for (n = 0; n < len;) {
1362 fprintf(stderr, "%04X: ", start);
1364 for (m = 0; m < 16 && n < len; m++)
1365 fprintf(stderr, "%02X ", buf[n++]);
1367 fprintf(stderr, " ");
1369 fprintf(stderr, " ");
1371 for (m = 0; m < 16 && (start + m) < len; m++) {
1372 if (buf[start + m] >= ' ' && buf[start + m] <= 127)
1373 fprintf(stderr, "%c", buf[start + m]);
1375 fprintf(stderr, ".");
1378 fprintf(stderr, " ");
1380 fprintf(stderr, "\n");
1382 fprintf(stderr, "\n");
1385 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
1391 * one of the extensions is carrying our data itself? Like mux?
1394 for (n = 0; n < wsi->count_active_extensions; n++) {
1396 * there can only be active extensions after handshake completed
1397 * so we can rely on protocol being set already in here
1399 m = wsi->active_extensions[n]->callback(
1400 wsi->protocol->owning_server,
1401 wsi->active_extensions[n], wsi,
1402 LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
1403 wsi->active_extensions_user[n], &buf, len);
1405 fprintf(stderr, "Extension reports fatal error\n");
1408 if (m) /* handled */ {
1409 // fprintf(stderr, "ext sent it\n");
1415 fprintf(stderr, "** error 0 sock but expected to send\n");
1419 * nope, send it on the socket directly
1423 fprintf(stderr, " TX: ");
1424 lws_stderr_hexdump(buf, len);
1427 #ifdef LWS_OPENSSL_SUPPORT
1429 n = SSL_write(wsi->ssl, buf, len);
1432 "ERROR writing to socket\n");
1437 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
1440 "ERROR writing to socket\n");
1443 #ifdef LWS_OPENSSL_SUPPORT
1450 lws_issue_raw_ext_access(struct libwebsocket *wsi,
1451 unsigned char *buf, size_t len)
1454 struct lws_tokens eff_buf;
1458 eff_buf.token = (char *)buf;
1459 eff_buf.token_len = len;
1462 * while we have original buf to spill ourselves, or extensions report
1463 * more in their pipeline
1469 /* default to nobody has more to spill */
1473 /* show every extension the new incoming data */
1475 for (n = 0; n < wsi->count_active_extensions; n++) {
1476 m = wsi->active_extensions[n]->callback(
1477 wsi->protocol->owning_server,
1478 wsi->active_extensions[n], wsi,
1479 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
1480 wsi->active_extensions_user[n], &eff_buf, 0);
1482 fprintf(stderr, "Extension reports fatal error\n");
1487 * at least one extension told us he has more
1488 * to spill, so we will go around again after
1493 /* assuming they left us something to send, send it */
1495 if (eff_buf.token_len)
1496 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
1500 /* we used up what we had */
1502 eff_buf.token = NULL;
1503 eff_buf.token_len = 0;
1506 * Did that leave the pipe choked?
1509 if (!lws_send_pipe_choked(wsi))
1510 /* no we could add more */
1513 fprintf(stderr, "choked\n");
1516 * Yes, he's choked. Don't spill the rest now get a callback
1517 * when he is ready to send and take care of it there
1519 libwebsocket_callback_on_writable(
1520 wsi->protocol->owning_server, wsi);
1521 wsi->extension_data_pending = 1;
1525 debug("written %d bytes to client\n", eff_buf.token_len);
1531 * libwebsocket_write() - Apply protocol then write data to client
1532 * @wsi: Websocket instance (available from user callback)
1533 * @buf: The data to send. For data being sent on a websocket
1534 * connection (ie, not default http), this buffer MUST have
1535 * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
1536 * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
1537 * in the buffer after (buf + len). This is so the protocol
1538 * header and trailer data can be added in-situ.
1539 * @len: Count of the data bytes in the payload starting from buf
1540 * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
1541 * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
1542 * data on a websockets connection. Remember to allow the extra
1543 * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
1546 * This function provides the way to issue data back to the client
1547 * for both http and websocket protocols.
1549 * In the case of sending using websocket protocol, be sure to allocate
1550 * valid storage before and after buf as explained above. This scheme
1551 * allows maximum efficiency of sending data and protocol in a single
1552 * packet while not burdening the user code with any protocol knowledge.
1555 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
1556 size_t len, enum libwebsocket_write_protocol protocol)
1562 int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT && wsi->xor_mask != xor_no_mask;
1563 unsigned char *dropmask = NULL;
1564 unsigned char is_masked_bit = 0;
1566 if (len == 0 && protocol != LWS_WRITE_CLOSE) {
1567 fprintf(stderr, "zero length libwebsocket_write attempt\n");
1571 if (protocol == LWS_WRITE_HTTP)
1574 /* websocket protocol, either binary or text */
1576 if (wsi->state != WSI_STATE_ESTABLISHED)
1579 switch (wsi->ietf_spec_revision) {
1580 /* chrome likes this as of 30 Oct 2010 */
1581 /* Firefox 4.0b6 likes this as of 30 Oct 2010 */
1583 if ((protocol & 0xf) == LWS_WRITE_BINARY) {
1584 /* in binary mode we send 7-bit used length blocks */
1586 while (len & (127 << shift)) {
1592 while (shift >= 0) {
1595 ((len >> shift) & 127) | 0x80;
1598 ((len >> shift) & 127);
1605 /* frame type = text, length-free spam mode */
1609 buf[len] = 0xff; /* EOT marker */
1618 dropmask = &buf[0 - pre];
1619 is_masked_bit = 0x80;
1625 switch (protocol & 0xf) {
1626 case LWS_WRITE_TEXT:
1627 if (wsi->ietf_spec_revision < 7)
1628 n = LWS_WS_OPCODE_04__TEXT_FRAME;
1630 n = LWS_WS_OPCODE_07__TEXT_FRAME;
1632 case LWS_WRITE_BINARY:
1633 if (wsi->ietf_spec_revision < 7)
1634 n = LWS_WS_OPCODE_04__BINARY_FRAME;
1636 n = LWS_WS_OPCODE_07__BINARY_FRAME;
1638 case LWS_WRITE_CONTINUATION:
1639 if (wsi->ietf_spec_revision < 7)
1640 n = LWS_WS_OPCODE_04__CONTINUATION;
1642 n = LWS_WS_OPCODE_07__CONTINUATION;
1645 case LWS_WRITE_CLOSE:
1646 if (wsi->ietf_spec_revision < 7)
1647 n = LWS_WS_OPCODE_04__CLOSE;
1649 n = LWS_WS_OPCODE_07__CLOSE;
1652 * v5 mandates the first byte of close packet
1653 * in both client and server directions
1656 switch (wsi->ietf_spec_revision) {
1661 /* we can do this because we demand post-buf */
1666 switch (wsi->mode) {
1667 case LWS_CONNMODE_WS_SERVING:
1669 fprintf(stderr, "LWS_WRITE_CLOSE S\n");
1673 case LWS_CONNMODE_WS_CLIENT:
1675 fprintf(stderr, "LWS_WRITE_CLOSE C\n");
1685 * 06 has a 2-byte status code in network order
1686 * we can do this because we demand post-buf
1689 if (wsi->close_reason) {
1690 /* reason codes count as data bytes */
1692 buf[0] = wsi->close_reason >> 8;
1693 buf[1] = wsi->close_reason;
1699 case LWS_WRITE_PING:
1700 if (wsi->ietf_spec_revision < 7)
1701 n = LWS_WS_OPCODE_04__PING;
1703 n = LWS_WS_OPCODE_07__PING;
1705 wsi->pings_vs_pongs++;
1707 case LWS_WRITE_PONG:
1708 if (wsi->ietf_spec_revision < 7)
1709 n = LWS_WS_OPCODE_04__PONG;
1711 n = LWS_WS_OPCODE_07__PONG;
1714 fprintf(stderr, "libwebsocket_write: unknown write "
1715 "opcode / protocol\n");
1719 if (!(protocol & LWS_WRITE_NO_FIN))
1725 buf[-pre + 1] = len | is_masked_bit;
1730 buf[-pre + 1] = 126 | is_masked_bit;
1731 buf[-pre + 2] = len >> 8;
1732 buf[-pre + 3] = len;
1736 buf[-pre + 1] = 127 | is_masked_bit;
1737 #if defined __LP64__
1738 buf[-pre + 2] = (len >> 56) & 0x7f;
1739 buf[-pre + 3] = len >> 48;
1740 buf[-pre + 4] = len >> 40;
1741 buf[-pre + 5] = len >> 32;
1748 buf[-pre + 6] = len >> 24;
1749 buf[-pre + 7] = len >> 16;
1750 buf[-pre + 8] = len >> 8;
1751 buf[-pre + 9] = len;
1758 * Deal with masking if we are in client -> server direction and
1759 * the protocol demands it
1762 if (wsi->mode == LWS_CONNMODE_WS_CLIENT &&
1763 wsi->ietf_spec_revision >= 4) {
1766 * this is only useful for security tests where it's required
1767 * to control the raw packet payload content
1770 if (!(protocol & LWS_WRITE_CLIENT_IGNORE_XOR_MASK) && wsi->xor_mask != xor_no_mask) {
1772 if (libwebsocket_0405_frame_mask_generate(wsi)) {
1773 fprintf(stderr, "libwebsocket_write: "
1774 "frame mask generation failed\n");
1779 if (wsi->ietf_spec_revision < 7)
1781 * use the XOR masking against everything we
1782 * send past the frame key
1784 for (n = -pre; n < ((int)len + post); n++)
1785 buf[n] = wsi->xor_mask(wsi, buf[n]);
1788 * in v7, just mask the payload
1790 for (n = 0; n < (int)len; n++)
1791 dropmask[n + 4] = wsi->xor_mask(wsi, dropmask[n + 4]);
1794 if (wsi->ietf_spec_revision < 7) {
1795 /* make space for the frame nonce in clear */
1798 dropmask = &buf[0 - pre];
1802 /* copy the frame nonce into place */
1803 memcpy(dropmask, wsi->frame_masking_nonce_04, 4);
1806 if (wsi->ietf_spec_revision < 7) {
1808 /* make space for the frame nonce in clear */
1816 if (dropmask && wsi->xor_mask != xor_no_mask) {
1830 fprintf(stderr, "send %ld: ", len + post);
1831 for (n = -pre; n < ((int)len + post); n++)
1832 fprintf(stderr, "%02X ", buf[n]);
1834 fprintf(stderr, "\n");
1837 if (protocol == LWS_WRITE_HTTP) {
1838 if (lws_issue_raw(wsi, (unsigned char *)buf - pre,
1846 * give any active extensions a chance to munge the buffer
1847 * before send. We pass in a pointer to an lws_tokens struct
1848 * prepared with the default buffer and content length that's in
1849 * there. Rather than rewrite the default buffer, extensions
1850 * that expect to grow the buffer can adapt .token to
1851 * point to their own per-connection buffer in the extension
1852 * user allocation. By default with no extensions or no
1853 * extension callback handling, just the normal input buffer is
1854 * used then so it is efficient.
1856 * callback returns 1 in case it wants to spill more buffers
1859 return lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
1864 * libwebsockets_serve_http_file() - Send a file back to the client using http
1865 * @wsi: Websocket instance (available from user callback)
1866 * @file: The file to issue over http
1867 * @content_type: The http content type, eg, text/html
1869 * This function is intended to be called from the callback in response
1870 * to http requests from the client. It allows the callback to issue
1871 * local files down the http link in a single step.
1874 int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
1875 const char *content_type)
1878 struct stat stat_buf;
1884 fd = open(file, O_RDONLY | _O_BINARY);
1886 fd = open(file, O_RDONLY);
1889 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
1890 "Server: libwebsockets\x0d\x0a"
1893 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
1899 fstat(fd, &stat_buf);
1900 p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
1901 "Server: libwebsockets\x0d\x0a"
1902 "Content-Type: %s\x0d\x0a"
1903 "Content-Length: %u\x0d\x0a"
1904 "\x0d\x0a", content_type, (unsigned int)stat_buf.st_size);
1906 libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
1910 n = read(fd, buf, 512);
1913 libwebsocket_write(wsi, (unsigned char *)buf, n,
1924 * libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
1925 * rx packet is complete
1926 * @wsi: Websocket instance (available from user callback)
1928 * This function is intended to be called from the callback if the
1929 * user code is interested in "complete packets" from the client.
1930 * libwebsockets just passes through payload as it comes and issues a buffer
1931 * additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE
1932 * callback handler can use this API to find out if the buffer it has just
1933 * been given is the last piece of a "complete packet" from the client --
1934 * when that is the case libwebsockets_remaining_packet_payload() will return
1937 * Many protocols won't care becuse their packets are always small.
1941 libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
1943 return wsi->rx_packet_length;