01d360b858867dc526b8d11da221d46a10b565a7
[profile/ivi/libwebsockets.git] / lib / parsers.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 Andy Green <andy@warmcat.com>
5  *
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.
10  *
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.
15  *
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,
19  *  MA  02110-1301  USA
20  */
21
22 #include "private-libwebsockets.h"
23
24 const struct lws_tokens lws_tokens[WSI_TOKEN_COUNT] = {
25
26         /* win32 can't do C99 */
27
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 },
38
39 /*      [WSI_TOKEN_KEY]         =       */{ "Sec-WebSocket-Key:",       18 },
40 /*      [WSI_TOKEN_VERSION]     =       */{ "Sec-WebSocket-Version:",   22 },
41 /*      [WSI_TOKEN_SWORIGIN]=           */{ "Sec-WebSocket-Origin:",    21 },
42
43 /*      [WSI_TOKEN_EXTENSIONS]  =       */{ "Sec-WebSocket-Extensions:", 25 },
44
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 },
49
50 };
51
52 int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
53 {
54         int n;
55
56         switch (wsi->parser_state) {
57         case WSI_TOKEN_GET_URI:
58         case WSI_TOKEN_HOST:
59         case WSI_TOKEN_CONNECTION:
60         case WSI_TOKEN_KEY1:
61         case WSI_TOKEN_KEY2:
62         case WSI_TOKEN_PROTOCOL:
63         case WSI_TOKEN_UPGRADE:
64         case WSI_TOKEN_ORIGIN:
65         case WSI_TOKEN_SWORIGIN:
66         case WSI_TOKEN_DRAFT:
67         case WSI_TOKEN_CHALLENGE:
68         case WSI_TOKEN_KEY:
69         case WSI_TOKEN_VERSION:
70         case WSI_TOKEN_ACCEPT:
71         case WSI_TOKEN_NONCE:
72         case WSI_TOKEN_EXTENSIONS:
73         case WSI_TOKEN_HTTP:
74         case WSI_TOKEN_MUXURL:
75
76                 debug("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c);
77
78                 /* collect into malloc'd buffers */
79                 /* optional space swallow */
80                 if (!wsi->utf8_token[wsi->parser_state].token_len && c == ' ')
81                         break;
82
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;
88                         break;
89                 }
90
91                 /* allocate appropriate memory */
92                 if (wsi->utf8_token[wsi->parser_state].token_len ==
93                                                    wsi->current_alloc_len - 1) {
94                         /* need to extend */
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;
101                                 break;
102                         }
103                         wsi->utf8_token[wsi->parser_state].token =
104                                realloc(wsi->utf8_token[wsi->parser_state].token,
105                                                         wsi->current_alloc_len);
106                 }
107
108                 /* bail at EOL */
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");
114                         break;
115                 }
116
117                 wsi->utf8_token[wsi->parser_state].token[
118                             wsi->utf8_token[wsi->parser_state].token_len++] = c;
119
120                 /* per-protocol end of headers management */
121
122                 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
123                         break;
124
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)
129                         break;
130
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)
135                         break;
136
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)
141                         break;
142
143                 /* no payload challenge in 01 + */
144
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;
150                 }
151
152                 /* For any supported protocol we have enough payload */
153
154                 debug("Setting WSI_PARSING_COMPLETE\n");
155                 wsi->parser_state = WSI_PARSING_COMPLETE;
156                 break;
157
158         case WSI_INIT_TOKEN_MUXURL:
159                 wsi->parser_state = WSI_TOKEN_MUXURL;
160                 wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
161
162                 wsi->utf8_token[wsi->parser_state].token =
163                                          malloc(wsi->current_alloc_len);
164                 wsi->utf8_token[wsi->parser_state].token_len = 0;
165                 break;
166
167                 /* collecting and checking a name part */
168         case WSI_TOKEN_NAME_PART:
169                 debug("WSI_TOKEN_NAME_PART '%c'\n", c);
170
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;
174                         break;
175                 }
176                 wsi->name_buffer[wsi->name_buffer_pos++] = c;
177                 wsi->name_buffer[wsi->name_buffer_pos] = '\0';
178
179                 for (n = 0; n < WSI_TOKEN_COUNT; n++) {
180                         if (wsi->name_buffer_pos != lws_tokens[n].token_len)
181                                 continue;
182                         if (strcmp(lws_tokens[n].token, wsi->name_buffer))
183                                 continue;
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;
187
188                         wsi->utf8_token[wsi->parser_state].token =
189                                                  malloc(wsi->current_alloc_len);
190                         wsi->utf8_token[wsi->parser_state].token_len = 0;
191                         n = WSI_TOKEN_COUNT;
192                 }
193
194                 /* colon delimiter means we just don't know this name */
195
196                 if (wsi->parser_state == WSI_TOKEN_NAME_PART && c == ':') {
197                         debug("skipping unknown header '%s'\n",
198                                                               wsi->name_buffer);
199                         wsi->parser_state = WSI_TOKEN_SKIPPING;
200                         break;
201                 }
202
203                 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
204                         break;
205
206                 /* don't look for payload when it can just be http headers */
207
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;
213                 }
214
215                 /* 04 version has no packet content after end of hdrs */
216
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;
224                 }
225
226                 /* client parser? */
227
228                 if (wsi->ietf_spec_revision >= 4) {
229                         debug("04 header completed\n");
230                         wsi->parser_state = WSI_PARSING_COMPLETE;
231                 }
232
233                 break;
234
235                 /* skipping arg part of a name we didn't recognize */
236         case WSI_TOKEN_SKIPPING:
237                 debug("WSI_TOKEN_SKIPPING '%c'\n", c);
238                 if (c == '\x0d')
239                         wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
240                 break;
241         case WSI_TOKEN_SKIPPING_SAW_CR:
242                 debug("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
243                 if (c == '\x0a')
244                         wsi->parser_state = WSI_TOKEN_NAME_PART;
245                 else
246                         wsi->parser_state = WSI_TOKEN_SKIPPING;
247                 wsi->name_buffer_pos = 0;
248                 break;
249                 /* we're done, ignore anything else */
250         case WSI_PARSING_COMPLETE:
251                 debug("WSI_PARSING_COMPLETE '%c'\n", c);
252                 break;
253
254         default:        /* keep gcc happy */
255                 break;
256         }
257
258         return 0;
259 }
260
261 unsigned char
262 xor_no_mask(struct libwebsocket *wsi, unsigned char c)
263 {
264         return c;
265 }
266
267 unsigned char
268 xor_mask_04(struct libwebsocket *wsi, unsigned char c)
269 {
270         c ^= wsi->masking_key_04[wsi->frame_mask_index++];
271         if (wsi->frame_mask_index == 20)
272                 wsi->frame_mask_index = 0;
273
274         return c;
275 }
276
277 unsigned char
278 xor_mask_05(struct libwebsocket *wsi, unsigned char c)
279 {
280         return c ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
281 }
282
283
284
285 int
286 libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
287 {
288         int n;
289         unsigned char buf[20 + 4];
290         struct lws_tokens eff_buf;
291         int handled;
292         int m;
293
294 //      fprintf(stderr, "RX: %02X ", c);
295
296         switch (wsi->lws_rx_parse_state) {
297         case LWS_RXPS_NEW:
298
299                 switch (wsi->ietf_spec_revision) {
300                 /* Firefox 4.0b6 likes this as of 30 Oct 2010 */
301                 case 0:
302                         if (c == 0xff)
303                                 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
304                         if (c == 0) {
305                                 wsi->lws_rx_parse_state =
306                                                        LWS_RXPS_EAT_UNTIL_76_FF;
307                                 wsi->rx_user_buffer_head = 0;
308                         }
309                         break;
310                 case 4:
311                 case 5:
312                 case 6:
313                         wsi->all_zero_nonce = 1;
314                         wsi->frame_masking_nonce_04[0] = c;
315                         if (c)
316                                 wsi->all_zero_nonce = 0;
317                         wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_1;
318                         break;
319                 case 7:
320                 case 8:
321                 case 13:
322                         /*
323                          * no prepended frame key any more
324                          */
325                         wsi->all_zero_nonce = 1;
326                         goto handle_first;
327
328                 default:
329                         fprintf(stderr, "libwebsocket_rx_sm doesn't know "
330                             "about spec version %d\n", wsi->ietf_spec_revision);
331                         break;
332                 }
333                 break;
334         case LWS_RXPS_04_MASK_NONCE_1:
335                 wsi->frame_masking_nonce_04[1] = c;
336                 if (c)
337                         wsi->all_zero_nonce = 0;
338                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
339                 break;
340         case LWS_RXPS_04_MASK_NONCE_2:
341                 wsi->frame_masking_nonce_04[2] = c;
342                 if (c)
343                         wsi->all_zero_nonce = 0;
344                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
345                 break;
346         case LWS_RXPS_04_MASK_NONCE_3:
347                 wsi->frame_masking_nonce_04[3] = c;
348                 if (c)
349                         wsi->all_zero_nonce = 0;
350
351                 if (wsi->protocol->owning_server->options &
352                                            LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK)
353                         goto post_mask;
354
355                 if (wsi->ietf_spec_revision > 4)
356                         goto post_sha1;
357
358                 /*
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.
364                  */
365
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];
370
371                 memcpy(buf + 4, wsi->masking_key_04, 20);
372
373                 /*
374                  * wsi->frame_mask_04 will be our recirculating 20-byte XOR key
375                  * for this frame
376                  */
377
378                 SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
379
380 post_sha1:
381
382                 /*
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
385                  */
386
387                 wsi->frame_mask_index = 0;
388
389 post_mask:
390                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
391                 break;
392
393         /*
394          *  04 logical framing from the spec (all this is masked when incoming
395          *  and has to be unmasked)
396          *
397          * We ignore the possibility of extension data because we don't
398          * negotiate any extensions at the moment.
399          *
400          *    0                   1                   2                   3
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)   |
406          *   | |1|2|3|       |4|             |                               |
407          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
408          *   |     Extended payload length continued, if payload len == 127  |
409          *   + - - - - - - - - - - - - - - - +-------------------------------+
410          *   |                               |         Extension data        |
411          *   +-------------------------------+ - - - - - - - - - - - - - - - +
412          *   :                                                               :
413          *   +---------------------------------------------------------------+
414          *   :                       Application data                        :
415          *   +---------------------------------------------------------------+
416          *
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
420          *  2^63 long!)
421          */
422
423         case LWS_RXPS_04_FRAME_HDR_1:
424 handle_first:
425
426                 /*
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)
430                  *
431                  *       frame-opcode           =
432                  *             %x0 ; continuation frame
433                  *              / %x1 ; connection close
434                  *              / %x2 ; ping
435                  *              / %x3 ; pong
436                  *              / %x4 ; text frame
437                  *              / %x5 ; binary frame
438                  *              / %x6-F ; reserved
439                  *
440                  *              FIN (b7)
441                  */
442
443                 if (wsi->ietf_spec_revision < 7)
444                         c = wsi->xor_mask(wsi, c);
445
446                 if (c & 0x70)
447                         fprintf(stderr,
448                             "Frame has unknown extension bits set 1 %02X\n", c);
449
450                 /* translate all incoming opcodes into v7+ map */
451                 if (wsi->ietf_spec_revision < 7)
452                         switch (c & 0xf) {
453                         case LWS_WS_OPCODE_04__CONTINUATION:
454                                 wsi->opcode = LWS_WS_OPCODE_07__CONTINUATION;
455                                 break;
456                         case LWS_WS_OPCODE_04__CLOSE:
457                                 wsi->opcode = LWS_WS_OPCODE_07__CLOSE;
458                                 break;
459                         case LWS_WS_OPCODE_04__PING:
460                                 wsi->opcode = LWS_WS_OPCODE_07__PING;
461                                 break;
462                         case LWS_WS_OPCODE_04__PONG:
463                                 wsi->opcode = LWS_WS_OPCODE_07__PONG;
464                                 break;
465                         case LWS_WS_OPCODE_04__TEXT_FRAME:
466                                 wsi->opcode = LWS_WS_OPCODE_07__TEXT_FRAME;
467                                 break;
468                         case LWS_WS_OPCODE_04__BINARY_FRAME:
469                                 wsi->opcode = LWS_WS_OPCODE_07__BINARY_FRAME;
470                                 break;
471                         default:
472                                 fprintf(stderr, "reserved opcodes not "
473                                                     "usable pre v7 protocol\n");
474                                 return -1;
475                         }
476                 else
477                         wsi->opcode = c & 0xf;
478
479                 wsi->final = !!((c >> 7) & 1);
480
481                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
482                 break;
483
484         case LWS_RXPS_04_FRAME_HDR_LEN:
485
486                 if (wsi->ietf_spec_revision < 7)
487                         c = wsi->xor_mask(wsi, c);
488
489                 if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
490                         fprintf(stderr, "Frame has extensions "
491                                                            "set illegally 2\n");
492                         /* kill the connection */
493                         return -1;
494                 }
495
496                 wsi->this_frame_masked = !!(c & 0x80);
497
498                 switch (c & 0x7f) {
499                 case 126:
500                         /* control frames are not allowed to have big lengths */
501                         if (wsi->opcode & 8)
502                                 goto illegal_ctl_length;
503
504                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
505                         break;
506                 case 127:
507                         /* control frames are not allowed to have big lengths */
508                         if (wsi->opcode & 8)
509                                 goto illegal_ctl_length;
510
511                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
512                         break;
513                 default:
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;
518                         else
519                                 wsi->lws_rx_parse_state =
520                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
521                         break;
522                 }
523                 break;
524
525         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
526                 if (wsi->ietf_spec_revision < 7)
527                         c = wsi->xor_mask(wsi, c);
528
529                 wsi->rx_packet_length = c << 8;
530                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
531                 break;
532
533         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
534                 if (wsi->ietf_spec_revision < 7)
535                         c = wsi->xor_mask(wsi, c);
536
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;
541                 else
542                         wsi->lws_rx_parse_state =
543                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
544                 break;
545
546         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
547                 if (wsi->ietf_spec_revision < 7)
548                         c = wsi->xor_mask(wsi, c);
549                 if (c & 0x80) {
550                         fprintf(stderr, "b63 of length must be zero\n");
551                         /* kill the connection */
552                         return -1;
553                 }
554 #if defined __LP64__
555                 wsi->rx_packet_length = ((size_t)c) << 56;
556 #else
557                 wsi->rx_packet_length = 0;
558 #endif
559                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
560                 break;
561
562         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
563                 if (wsi->ietf_spec_revision < 7)
564                         c = wsi->xor_mask(wsi, c);
565 #if defined __LP64__
566                 wsi->rx_packet_length |= ((size_t)c) << 48;
567 #endif
568                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
569                 break;
570
571         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
572                 if (wsi->ietf_spec_revision < 7)
573                         c = wsi->xor_mask(wsi, c);
574 #if defined __LP64__
575                 wsi->rx_packet_length |= ((size_t)c) << 40;
576 #endif
577                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
578                 break;
579
580         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
581                 if (wsi->ietf_spec_revision < 7)
582                         c = wsi->xor_mask(wsi, c);
583 #if defined __LP64__
584                 wsi->rx_packet_length |= ((size_t)c) << 32;
585 #endif
586                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
587                 break;
588
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;
594                 break;
595
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;
601                 break;
602
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;
608                 break;
609
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;
617                 else
618                         wsi->lws_rx_parse_state =
619                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
620                 break;
621
622         case LWS_RXPS_EAT_UNTIL_76_FF:
623                 if (c == 0xff) {
624                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
625                         goto issue;
626                 }
627                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
628                                               (wsi->rx_user_buffer_head++)] = c;
629
630                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
631                         break;
632 issue:
633                 if (wsi->protocol->callback)
634                         wsi->protocol->callback(wsi->protocol->owning_server,
635                           wsi, LWS_CALLBACK_RECEIVE,
636                           wsi->user_space,
637                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
638                           wsi->rx_user_buffer_head);
639                 wsi->rx_user_buffer_head = 0;
640                 break;
641         case LWS_RXPS_SEEN_76_FF:
642                 if (c)
643                         break;
644
645                 debug("Seen that client is requesting "
646                                 "a v76 close, sending ack\n");
647                 buf[0] = 0xff;
648                 buf[1] = 0;
649                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
650                 if (n < 0) {
651                         fprintf(stderr, "ERROR writing to socket");
652                         return -1;
653                 }
654                 debug("  v76 close ack sent, server closing skt\n");
655                 /* returning < 0 will get it closed in parent */
656                 return -1;
657
658         case LWS_RXPS_PULLING_76_LENGTH:
659                 break;
660
661
662         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
663                 wsi->frame_masking_nonce_04[0] = c;
664                 if (c)
665                         wsi->all_zero_nonce = 0;
666                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
667                 break;
668
669         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
670                 wsi->frame_masking_nonce_04[1] = c;
671                 if (c)
672                         wsi->all_zero_nonce = 0;
673                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
674                 break;
675
676         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
677                 wsi->frame_masking_nonce_04[2] = c;
678                 if (c)
679                         wsi->all_zero_nonce = 0;
680                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
681                 break;
682
683         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
684                 wsi->frame_masking_nonce_04[3] = c;
685                 if (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;
690                 break;
691
692
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;
697                 else
698                         wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
699                                (wsi->rx_user_buffer_head++)] =
700                                                           wsi->xor_mask(wsi, c);
701
702                 if (--wsi->rx_packet_length == 0) {
703                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
704                         goto spill;
705                 }
706                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
707                         break;
708 spill:
709                 /*
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
712                  */
713
714                 debug("spill on %s\n", wsi->protocol->name);
715
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) {
720                                 /*
721                                  * fine he has told us he is closing too, let's
722                                  * finish our close
723                                  */
724                                 fprintf(stderr, "seen client close ack\n");
725                                 return -1;
726                         }
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 */
734                         return -1;
735
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;
743                         return 0;
744
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;
750                         return 0;
751
752                 case LWS_WS_OPCODE_07__TEXT_FRAME:
753                 case LWS_WS_OPCODE_07__BINARY_FRAME:
754                         break;
755
756                 default:
757
758                         debug("passing opcode %x up to exts\n", wsi->opcode);
759
760                         /*
761                          * It's something special we can't understand here.
762                          * Pass the payload up to the extension's parsing
763                          * state machine.
764                          */
765
766                         eff_buf.token = &wsi->rx_user_buffer[
767                                                    LWS_SEND_BUFFER_PRE_PADDING];
768                         eff_buf.token_len = wsi->rx_user_buffer_head;
769
770                         handled = 0;
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],
777                                                                    &eff_buf, 0);
778                                 if (m)
779                                         handled = 1;
780                         }
781
782                         if (!handled)
783                                 fprintf(stderr, "Unhandled extended opcode "
784                                         "0x%x - ignoring frame\n", wsi->opcode);
785
786                         wsi->rx_user_buffer_head = 0;
787                         return 0;
788                 }
789
790                 /*
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
794                  */
795
796                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
797                                                wsi->rx_user_buffer_head] = '\0';
798
799                 if (wsi->protocol->callback)
800                         wsi->protocol->callback(wsi->protocol->owning_server,
801                                                 wsi, LWS_CALLBACK_RECEIVE,
802                                                 wsi->user_space,
803                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
804                                                       wsi->rx_user_buffer_head);
805                 else
806                         fprintf(stderr, "No callback on payload spill!\n");
807
808                 wsi->rx_user_buffer_head = 0;
809                 break;
810         }
811
812         return 0;
813
814 illegal_ctl_length:
815
816         fprintf(stderr, "Control frame asking for "
817                         "extended length is illegal\n");
818         /* kill the connection */
819         return -1;
820 }
821
822
823 int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
824 {
825         int n;
826         unsigned char buf[20 + 4];
827         int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
828         int handled;
829         struct lws_tokens eff_buf;
830         int m;
831
832         debug(" CRX: %02X %d\n", c, wsi->lws_rx_parse_state);
833
834         switch (wsi->lws_rx_parse_state) {
835         case LWS_RXPS_NEW:
836
837                 switch (wsi->ietf_spec_revision) {
838                 /* Firefox 4.0b6 likes this as of 30 Oct */
839                 case 0:
840                         if (c == 0xff)
841                                 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
842                         if (c == 0) {
843                                 wsi->lws_rx_parse_state =
844                                                        LWS_RXPS_EAT_UNTIL_76_FF;
845                                 wsi->rx_user_buffer_head = 0;
846                         }
847                         break;
848                 case 4:
849                 case 5:
850                 case 6:
851                 case 7:
852                 case 8:
853                 case 13:
854         /*
855          *  04 logical framing from the spec (all this is masked when
856          *  incoming and has to be unmasked)
857          *
858          * We ignore the possibility of extension data because we don't
859          * negotiate any extensions at the moment.
860          *
861          *    0                   1                   2                   3
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)   |
867          *   | |1|2|3|       |4|             |                               |
868          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
869          *   |     Extended payload length continued, if payload len == 127  |
870          *   + - - - - - - - - - - - - - - - +-------------------------------+
871          *   |                               |         Extension data        |
872          *   +-------------------------------+ - - - - - - - - - - - - - - - +
873          *   :                                                               :
874          *   +---------------------------------------------------------------+
875          *   :                       Application data                        :
876          *   +---------------------------------------------------------------+
877          *
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
881          *  2^63 long!)
882          *
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.
886          */
887
888                 /*
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)
892                  *
893                  *       frame-opcode           =
894                  *                %x0 ; continuation frame
895                  *              / %x1 ; connection close
896                  *              / %x2 ; ping
897                  *              / %x3 ; pong
898                  *              / %x4 ; text frame
899                  *              / %x5 ; binary frame
900                  *              / %x6-F ; reserved
901                  *
902                  *              FIN (b7)
903                  */
904
905                         if (c & 0x70)
906                                 fprintf(stderr, "Frame has unknown extension "
907                                     "bits set on first framing byte %02X\n", c);
908
909                         if (wsi->ietf_spec_revision < 7)
910                                 switch (c & 0xf) {
911                                 case LWS_WS_OPCODE_04__CONTINUATION:
912                                         wsi->opcode = LWS_WS_OPCODE_07__CONTINUATION;
913                                         break;
914                                 case LWS_WS_OPCODE_04__CLOSE:
915                                         wsi->opcode = LWS_WS_OPCODE_07__CLOSE;
916                                         break;
917                                 case LWS_WS_OPCODE_04__PING:
918                                         wsi->opcode = LWS_WS_OPCODE_07__PING;
919                                         break;
920                                 case LWS_WS_OPCODE_04__PONG:
921                                         wsi->opcode = LWS_WS_OPCODE_07__PONG;
922                                         break;
923                                 case LWS_WS_OPCODE_04__TEXT_FRAME:
924                                         wsi->opcode = LWS_WS_OPCODE_07__TEXT_FRAME;
925                                         break;
926                                 case LWS_WS_OPCODE_04__BINARY_FRAME:
927                                         wsi->opcode = LWS_WS_OPCODE_07__BINARY_FRAME;
928                                         break;
929                                 default:
930                                         fprintf(stderr, "reserved opcodes not "
931                                                             "usable pre v7 protocol\n");
932                                         return -1;
933                                 }
934                         else
935                                 wsi->opcode = c & 0xf;
936
937                         wsi->final = !!((c >> 7) & 1);
938
939                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
940                         break;
941
942                 default:
943                         fprintf(stderr, "client_rx_sm doesn't know how "
944                                 "to handle spec version %02d\n",
945                                                        wsi->ietf_spec_revision);
946                         break;
947                 }
948                 break;
949
950
951         case LWS_RXPS_04_FRAME_HDR_LEN:
952
953                 if ((c & 0x80) && wsi->ietf_spec_revision < 7) {
954                         fprintf(stderr,
955                                       "Frame has extensions set illegally 4\n");
956                         /* kill the connection */
957                         return -1;
958                 }
959
960                 wsi->this_frame_masked = !!(c & 0x80);
961
962                 switch (c & 0x7f) {
963                 case 126:
964                         /* control frames are not allowed to have big lengths */
965                         if (wsi->opcode & 8)
966                                 goto illegal_ctl_length;
967                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
968                         break;
969                 case 127:
970                         /* control frames are not allowed to have big lengths */
971                         if (wsi->opcode & 8)
972                                 goto illegal_ctl_length;
973                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
974                         break;
975                 default:
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;
980                         else {
981                                 if (c)
982                                         wsi->lws_rx_parse_state =
983                                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
984                                 else {
985                                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
986                                         goto spill;
987                                 }
988                         }
989                         break;
990                 }
991                 break;
992
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;
996                 break;
997
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;
1003                 else {
1004                         if (wsi->rx_packet_length)
1005                                 wsi->lws_rx_parse_state =
1006                                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1007                         else {
1008                                 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1009                                 goto spill;
1010                         }
1011                 }
1012                 break;
1013
1014         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
1015                 if (c & 0x80) {
1016                         fprintf(stderr, "b63 of length must be zero\n");
1017                         /* kill the connection */
1018                         return -1;
1019                 }
1020 #if defined __LP64__
1021                 wsi->rx_packet_length = ((size_t)c) << 56;
1022 #else
1023                 wsi->rx_packet_length = 0;
1024 #endif
1025                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
1026                 break;
1027
1028         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
1029 #if defined __LP64__
1030                 wsi->rx_packet_length |= ((size_t)c) << 48;
1031 #endif
1032                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
1033                 break;
1034
1035         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
1036 #if defined __LP64__
1037                 wsi->rx_packet_length |= ((size_t)c) << 40;
1038 #endif
1039                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
1040                 break;
1041
1042         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
1043 #if defined __LP64__
1044                 wsi->rx_packet_length |= ((size_t)c) << 32;
1045 #endif
1046                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
1047                 break;
1048
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;
1052                 break;
1053
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;
1057                 break;
1058
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;
1062                 break;
1063
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;
1069                 else {
1070                         if (wsi->rx_packet_length)
1071                                 wsi->lws_rx_parse_state =
1072                                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1073                         else {
1074                                 wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1075                                 goto spill;
1076                         }
1077                 }
1078                 break;
1079
1080         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
1081                 wsi->frame_masking_nonce_04[0] = c;
1082                 if (c)
1083                         wsi->all_zero_nonce = 0;
1084                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
1085                 break;
1086
1087         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
1088                 wsi->frame_masking_nonce_04[1] = c;
1089                 if (c)
1090                         wsi->all_zero_nonce = 0;
1091                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
1092                 break;
1093
1094         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
1095                 wsi->frame_masking_nonce_04[2] = c;
1096                 if (c)
1097                         wsi->all_zero_nonce = 0;
1098                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
1099                 break;
1100
1101         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
1102                 wsi->frame_masking_nonce_04[3] = c;
1103                 if (c)
1104                         wsi->all_zero_nonce = 0;
1105
1106                 if (wsi->rx_packet_length)
1107                         wsi->lws_rx_parse_state =
1108                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1109                 else {
1110                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1111                         goto spill;
1112                 }
1113                 break;
1114
1115         case LWS_RXPS_EAT_UNTIL_76_FF:
1116                 if (c == 0xff) {
1117                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1118                         goto issue;
1119                 }
1120                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
1121                                               (wsi->rx_user_buffer_head++)] = c;
1122
1123                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
1124                         break;
1125 issue:
1126                 if (wsi->protocol->callback)
1127                         wsi->protocol->callback(wsi->protocol->owning_server,
1128                                                 wsi,
1129                                                 LWS_CALLBACK_CLIENT_RECEIVE,
1130                                                 wsi->user_space,
1131                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1132                                                       wsi->rx_user_buffer_head);
1133                 wsi->rx_user_buffer_head = 0;
1134                 break;
1135         case LWS_RXPS_SEEN_76_FF:
1136                 if (c)
1137                         break;
1138
1139                 debug("Seen that client is requesting "
1140                                 "a v76 close, sending ack\n");
1141                 buf[0] = 0xff;
1142                 buf[1] = 0;
1143                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
1144                 if (n < 0) {
1145                         fprintf(stderr, "ERROR writing to socket");
1146                         return -1;
1147                 }
1148                 debug("  v76 close ack sent, server closing skt\n");
1149                 /* returning < 0 will get it closed in parent */
1150                 return -1;
1151
1152         case LWS_RXPS_PULLING_76_LENGTH:
1153                 break;
1154
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;
1159                 else
1160                         wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
1161                                (wsi->rx_user_buffer_head++)] =
1162                                                           wsi->xor_mask(wsi, c);
1163
1164                 if (--wsi->rx_packet_length == 0) {
1165                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1166                         goto spill;
1167                 }
1168                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
1169                         break;
1170 spill:
1171
1172                 handled = 0;
1173
1174                 /*
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
1177                  */
1178
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) {
1183                                 /*
1184                                  * fine he has told us he is closing too, let's
1185                                  * finish our close
1186                                  */
1187                                 fprintf(stderr, "seen server's close ack\n");
1188                                 return -1;
1189                         }
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 */
1198                         return -1;
1199
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);
1205                         handled = 1;
1206                         break;
1207
1208                 case LWS_WS_OPCODE_07__PONG:
1209                         /* keep the statistics... */
1210                         wsi->pings_vs_pongs--;
1211
1212                         /* issue it */
1213                         callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
1214                         break;
1215
1216                 case LWS_WS_OPCODE_07__CONTINUATION:
1217                 case LWS_WS_OPCODE_07__TEXT_FRAME:
1218                 case LWS_WS_OPCODE_07__BINARY_FRAME:
1219                         break;
1220
1221                 default:
1222
1223                         fprintf(stderr, "Reserved opcode 0x%2X\n", wsi->opcode);
1224                         /*
1225                          * It's something special we can't understand here.
1226                          * Pass the payload up to the extension's parsing
1227                          * state machine.
1228                          */
1229
1230                         eff_buf.token = &wsi->rx_user_buffer[
1231                                                    LWS_SEND_BUFFER_PRE_PADDING];
1232                         eff_buf.token_len = wsi->rx_user_buffer_head;
1233
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],
1240                                                                    &eff_buf, 0);
1241                                 if (m)
1242                                         handled = 1;
1243                         }
1244
1245                         if (!handled) {
1246                                 fprintf(stderr, "Unhandled extended opcode "
1247                                         "0x%x - ignoring frame\n", wsi->opcode);
1248                                 wsi->rx_user_buffer_head = 0;
1249
1250                                 return 0;
1251                         }
1252
1253                         break;
1254                 }
1255
1256                 /*
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
1260                  */
1261
1262                 if (!handled && wsi->protocol->callback)
1263                         wsi->protocol->callback(wsi->protocol->owning_server,
1264                                                 wsi, callback_action,
1265                                                 wsi->user_space,
1266                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1267                                                       wsi->rx_user_buffer_head);
1268                 wsi->rx_user_buffer_head = 0;
1269                 break;
1270         default:
1271                 fprintf(stderr, "client rx illegal state\n");
1272                 return 1;
1273         }
1274
1275         return 0;
1276
1277 illegal_ctl_length:
1278
1279         fprintf(stderr, "Control frame asking for "
1280                                 "extended length is illegal\n");
1281         /* kill the connection */
1282         return -1;
1283
1284 }
1285
1286
1287
1288 int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
1289                                                  unsigned char *buf, size_t len)
1290 {
1291         int n;
1292
1293 #ifdef DEBUG
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");
1298 #endif
1299
1300         /* let the rx protocol state machine have as much as it needs */
1301
1302         n = 0;
1303         while (n < len)
1304                 if (libwebsocket_rx_sm(wsi, buf[n++]) < 0)
1305                         return -1;
1306
1307         return 0;
1308 }
1309
1310
1311 static int
1312 libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
1313 {
1314         char buf[4 + 20];
1315         int n;
1316
1317         /* fetch the per-frame nonce */
1318
1319         n = libwebsockets_get_random(wsi->protocol->owning_server,
1320                                                 wsi->frame_masking_nonce_04, 4);
1321         if (n != 4) {
1322                 fprintf(stderr, "Unable to read from random device %s %d\n",
1323                                                      SYSTEM_RANDOM_FILEPATH, n);
1324                 return 1;
1325         }
1326
1327         /* start masking from first byte of masking key buffer */
1328         wsi->frame_mask_index = 0;
1329
1330         if (wsi->ietf_spec_revision != 4)
1331                 return 0;
1332
1333         /* 04 only does SHA-1 more complex key */
1334
1335         /*
1336          * the frame key is the frame nonce (4 bytes) followed by the
1337          * connection masking key, hashed by SHA1
1338          */
1339
1340         memcpy(buf, wsi->frame_masking_nonce_04, 4);
1341         
1342         memcpy(buf + 4, wsi->masking_key_04, 20);
1343
1344         /* concatenate the nonce with the connection key then hash it */
1345
1346         SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
1347
1348         return 0;
1349 }
1350
1351 void lws_stderr_hexdump(unsigned char *buf, size_t len)
1352 {
1353         int n;
1354         int m;
1355         int start;
1356
1357         fprintf(stderr, "\n");
1358
1359         for (n = 0; n < len;) {
1360                 start = n;
1361
1362                 fprintf(stderr, "%04X: ", start);
1363                 
1364                 for (m = 0; m < 16 && n < len; m++)
1365                         fprintf(stderr, "%02X ", buf[n++]);
1366                 while (m++ < 16)
1367                         fprintf(stderr, "   ");
1368
1369                 fprintf(stderr, "   ");
1370
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]);
1374                         else
1375                                 fprintf(stderr, ".");
1376                 }
1377                 while (m++ < 16)
1378                         fprintf(stderr, " ");
1379
1380                 fprintf(stderr, "\n");
1381         }
1382         fprintf(stderr, "\n");
1383 }
1384
1385 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
1386 {
1387         int n;
1388         int m;
1389
1390         /*
1391          * one of the extensions is carrying our data itself?  Like mux?
1392          */
1393
1394         for (n = 0; n < wsi->count_active_extensions; n++) {
1395                 /*
1396                  * there can only be active extensions after handshake completed
1397                  * so we can rely on protocol being set already in here
1398                  */
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);
1404                 if (m < 0) {
1405                         fprintf(stderr, "Extension reports fatal error\n");
1406                         return -1;
1407                 }
1408                 if (m) /* handled */ {
1409 //                      fprintf(stderr, "ext sent it\n");
1410                         return 0;
1411                 }
1412         }
1413
1414         if (!wsi->sock) {
1415                 fprintf(stderr, "** error 0 sock but expected to send\n");
1416         }
1417
1418         /*
1419          * nope, send it on the socket directly
1420          */
1421
1422 #if 0
1423         fprintf(stderr, "  TX: ");
1424         lws_stderr_hexdump(buf, len);
1425 #endif
1426
1427 #ifdef LWS_OPENSSL_SUPPORT
1428         if (wsi->ssl) {
1429                 n = SSL_write(wsi->ssl, buf, len);
1430                 if (n < 0) {
1431                         fprintf(stderr,
1432                                    "ERROR writing to socket\n");
1433                         return -1;
1434                 }
1435         } else {
1436 #endif
1437                 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
1438                 if (n < 0) {
1439                         fprintf(stderr,
1440                                    "ERROR writing to socket\n");
1441                         return -1;
1442                 }
1443 #ifdef LWS_OPENSSL_SUPPORT
1444         }
1445 #endif
1446         return 0;
1447 }
1448
1449 int
1450 lws_issue_raw_ext_access(struct libwebsocket *wsi,
1451                                                  unsigned char *buf, size_t len)
1452 {
1453         int ret;
1454         struct lws_tokens eff_buf;
1455         int m;
1456         int n;
1457
1458         eff_buf.token = (char *)buf;
1459         eff_buf.token_len = len;
1460
1461         /*
1462          * while we have original buf to spill ourselves, or extensions report
1463          * more in their pipeline
1464          */
1465
1466         ret = 1;
1467         while (ret == 1) {
1468
1469                 /* default to nobody has more to spill */
1470
1471                 ret = 0;
1472
1473                 /* show every extension the new incoming data */
1474
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);
1481                         if (m < 0) {
1482                                 fprintf(stderr, "Extension reports fatal error\n");
1483                                 return -1;
1484                         }
1485                         if (m)
1486                                 /*
1487                                  * at least one extension told us he has more
1488                                  * to spill, so we will go around again after
1489                                  */
1490                                 ret = 1;
1491                 }
1492
1493                 /* assuming they left us something to send, send it */
1494
1495                 if (eff_buf.token_len)
1496                         if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
1497                                                              eff_buf.token_len))
1498                                 return -1;
1499
1500                 /* we used up what we had */
1501
1502                 eff_buf.token = NULL;
1503                 eff_buf.token_len = 0;
1504
1505                 /*
1506                  * Did that leave the pipe choked?
1507                  */
1508
1509                 if (!lws_send_pipe_choked(wsi))
1510                         /* no we could add more */
1511                         continue;
1512
1513                 fprintf(stderr, "choked\n");
1514
1515                 /*
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
1518                  */
1519                 libwebsocket_callback_on_writable(
1520                                              wsi->protocol->owning_server, wsi);
1521                 wsi->extension_data_pending = 1;
1522                 ret = 0;
1523         }
1524
1525         debug("written %d bytes to client\n", eff_buf.token_len);
1526
1527         return 0;
1528 }
1529
1530 /**
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
1544  *              are used.
1545  *
1546  *      This function provides the way to issue data back to the client
1547  *      for both http and websocket protocols.
1548  *
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.
1553  */
1554
1555 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
1556                           size_t len, enum libwebsocket_write_protocol protocol)
1557 {
1558         int n;
1559         int pre = 0;
1560         int post = 0;
1561         int shift = 7;
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;
1565
1566         if (len == 0 && protocol != LWS_WRITE_CLOSE) {
1567                 fprintf(stderr, "zero length libwebsocket_write attempt\n");
1568                 return 0;
1569         }
1570
1571         if (protocol == LWS_WRITE_HTTP)
1572                 goto send_raw;
1573
1574         /* websocket protocol, either binary or text */
1575
1576         if (wsi->state != WSI_STATE_ESTABLISHED)
1577                 return -1;
1578
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 */
1582         case 0:
1583                 if ((protocol & 0xf) == LWS_WRITE_BINARY) {
1584                         /* in binary mode we send 7-bit used length blocks */
1585                         pre = 1;
1586                         while (len & (127 << shift)) {
1587                                 pre++;
1588                                 shift += 7;
1589                         }
1590                         n = 0;
1591                         shift -= 7;
1592                         while (shift >= 0) {
1593                                 if (shift)
1594                                         buf[0 - pre + n] =
1595                                                   ((len >> shift) & 127) | 0x80;
1596                                 else
1597                                         buf[0 - pre + n] =
1598                                                   ((len >> shift) & 127);
1599                                 n++;
1600                                 shift -= 7;
1601                         }
1602                         break;
1603                 }
1604
1605                 /* frame type = text, length-free spam mode */
1606
1607                 pre = 1;
1608                 buf[-pre] = 0;
1609                 buf[len] = 0xff; /* EOT marker */
1610                 post = 1;
1611                 break;
1612
1613         case 7:
1614         case 8:
1615         case 13:
1616                 if (masked7) {
1617                         pre += 4;
1618                         dropmask = &buf[0 - pre];
1619                         is_masked_bit = 0x80;
1620                 }
1621                 /* fallthru */
1622         case 4:
1623         case 5:
1624         case 6:
1625                 switch (protocol & 0xf) {
1626                 case LWS_WRITE_TEXT:
1627                         if (wsi->ietf_spec_revision < 7)
1628                                 n = LWS_WS_OPCODE_04__TEXT_FRAME;
1629                         else
1630                                 n = LWS_WS_OPCODE_07__TEXT_FRAME;
1631                         break;
1632                 case LWS_WRITE_BINARY:
1633                         if (wsi->ietf_spec_revision < 7)
1634                                 n = LWS_WS_OPCODE_04__BINARY_FRAME;
1635                         else
1636                                 n = LWS_WS_OPCODE_07__BINARY_FRAME;
1637                         break;
1638                 case LWS_WRITE_CONTINUATION:
1639                         if (wsi->ietf_spec_revision < 7)
1640                                 n = LWS_WS_OPCODE_04__CONTINUATION;
1641                         else
1642                                 n = LWS_WS_OPCODE_07__CONTINUATION;
1643                         break;
1644
1645                 case LWS_WRITE_CLOSE:
1646                         if (wsi->ietf_spec_revision < 7)
1647                                 n = LWS_WS_OPCODE_04__CLOSE;
1648                         else
1649                                 n = LWS_WS_OPCODE_07__CLOSE;
1650
1651                         /*
1652                          * v5 mandates the first byte of close packet
1653                          * in both client and server directions
1654                          */
1655                         
1656                         switch (wsi->ietf_spec_revision) {
1657                         case 0:
1658                         case 4:
1659                                 break;
1660                         case 5:
1661                                 /* we can do this because we demand post-buf */
1662
1663                                 if (len < 1)
1664                                         len = 1;
1665                                 
1666                                 switch (wsi->mode) {
1667                                 case LWS_CONNMODE_WS_SERVING:
1668                                         /*
1669                                         fprintf(stderr, "LWS_WRITE_CLOSE S\n");
1670                                         */
1671                                         buf[0] = 'S';
1672                                         break;
1673                                 case LWS_CONNMODE_WS_CLIENT:
1674                                         /*
1675                                         fprintf(stderr, "LWS_WRITE_CLOSE C\n");
1676                                         */
1677                                         buf[0] = 'C';
1678                                         break;
1679                                 default:
1680                                         break;
1681                                 }
1682                                 break;
1683                         default:
1684                                 /*
1685                                  * 06 has a 2-byte status code in network order
1686                                  * we can do this because we demand post-buf
1687                                  */
1688
1689                                 if (wsi->close_reason) {
1690                                         /* reason codes count as data bytes */
1691                                         buf -= 2;
1692                                         buf[0] = wsi->close_reason >> 8;
1693                                         buf[1] = wsi->close_reason;
1694                                         len += 2;
1695                                 }
1696                                 break;
1697                         }
1698                         break;
1699                 case LWS_WRITE_PING:
1700                         if (wsi->ietf_spec_revision < 7)
1701                                 n = LWS_WS_OPCODE_04__PING;
1702                         else
1703                                 n = LWS_WS_OPCODE_07__PING;
1704
1705                         wsi->pings_vs_pongs++;
1706                         break;
1707                 case LWS_WRITE_PONG:
1708                         if (wsi->ietf_spec_revision < 7)
1709                                 n = LWS_WS_OPCODE_04__PONG;
1710                         else
1711                                 n = LWS_WS_OPCODE_07__PONG;
1712                         break;
1713                 default:
1714                         fprintf(stderr, "libwebsocket_write: unknown write "
1715                                                          "opcode / protocol\n");
1716                         return -1;
1717                 }
1718
1719                 if (!(protocol & LWS_WRITE_NO_FIN))
1720                         n |= 1 << 7;
1721
1722                 if (len < 126) {
1723                         pre += 2;
1724                         buf[-pre] = n;
1725                         buf[-pre + 1] = len | is_masked_bit;
1726                 } else {
1727                         if (len < 65536) {
1728                                 pre += 4;
1729                                 buf[-pre] = n;
1730                                 buf[-pre + 1] = 126 | is_masked_bit;
1731                                 buf[-pre + 2] = len >> 8;
1732                                 buf[-pre + 3] = len;
1733                         } else {
1734                                 pre += 10;
1735                                 buf[-pre] = n;
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;
1742 #else
1743                                         buf[-pre + 2] = 0;
1744                                         buf[-pre + 3] = 0;
1745                                         buf[-pre + 4] = 0;
1746                                         buf[-pre + 5] = 0;
1747 #endif
1748                                 buf[-pre + 6] = len >> 24;
1749                                 buf[-pre + 7] = len >> 16;
1750                                 buf[-pre + 8] = len >> 8;
1751                                 buf[-pre + 9] = len;
1752                         }
1753                 }
1754                 break;
1755         }
1756
1757         /*
1758          * Deal with masking if we are in client -> server direction and
1759          * the protocol demands it
1760          */
1761
1762         if (wsi->mode == LWS_CONNMODE_WS_CLIENT &&
1763                                                  wsi->ietf_spec_revision >= 4) {
1764
1765                 /*
1766                  * this is only useful for security tests where it's required
1767                  * to control the raw packet payload content
1768                  */
1769
1770                 if (!(protocol & LWS_WRITE_CLIENT_IGNORE_XOR_MASK) && wsi->xor_mask != xor_no_mask) {
1771
1772                         if (libwebsocket_0405_frame_mask_generate(wsi)) {
1773                                 fprintf(stderr, "libwebsocket_write: "
1774                                               "frame mask generation failed\n");
1775                                 return 1;
1776                         }
1777
1778
1779                         if (wsi->ietf_spec_revision < 7)
1780                                 /*
1781                                  * use the XOR masking against everything we
1782                                  * send past the frame key
1783                                  */
1784                                 for (n = -pre; n < ((int)len + post); n++)
1785                                         buf[n] = wsi->xor_mask(wsi, buf[n]);
1786                         else
1787                                 /*
1788                                  * in v7, just mask the payload
1789                                  */
1790                                 for (n = 0; n < (int)len; n++)
1791                                         dropmask[n + 4] = wsi->xor_mask(wsi, dropmask[n + 4]);
1792
1793
1794                         if (wsi->ietf_spec_revision < 7) {
1795                                 /* make space for the frame nonce in clear */
1796                                 pre += 4;
1797
1798                                 dropmask = &buf[0 - pre];
1799                         }
1800
1801                         if (dropmask)
1802                                 /* copy the frame nonce into place */
1803                                 memcpy(dropmask, wsi->frame_masking_nonce_04, 4);
1804
1805                 } else {
1806                         if (wsi->ietf_spec_revision < 7) {
1807
1808                                 /* make space for the frame nonce in clear */
1809                                 pre += 4;
1810
1811                                 buf[0 - pre] = 0;
1812                                 buf[1 - pre] = 0;
1813                                 buf[2 - pre] = 0;
1814                                 buf[3 - pre] = 0;
1815                         } else {
1816                                 if (dropmask && wsi->xor_mask != xor_no_mask) {
1817                                         dropmask[0] = 0;
1818                                         dropmask[1] = 0;
1819                                         dropmask[2] = 0;
1820                                         dropmask[3] = 0;
1821                                 }
1822                         }
1823                 }
1824
1825         }
1826
1827 send_raw:
1828
1829 #if 0
1830         fprintf(stderr, "send %ld: ", len + post);
1831         for (n = -pre; n < ((int)len + post); n++)
1832                 fprintf(stderr, "%02X ", buf[n]);
1833
1834         fprintf(stderr, "\n");
1835 #endif
1836
1837         if (protocol == LWS_WRITE_HTTP) {
1838                 if (lws_issue_raw(wsi, (unsigned char *)buf - pre,
1839                                                               len + pre + post))
1840                         return -1;
1841
1842                 return 0;
1843         }
1844
1845         /*
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.
1855          *
1856          * callback returns 1 in case it wants to spill more buffers
1857          */
1858
1859         return lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
1860 }
1861
1862
1863 /**
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
1868  *
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.
1872  */
1873
1874 int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
1875                                                        const char *content_type)
1876 {
1877         int fd;
1878         struct stat stat_buf;
1879         char buf[512];
1880         char *p = buf;
1881         int n;
1882
1883 #ifdef WIN32
1884         fd = open(file, O_RDONLY | _O_BINARY);
1885 #else
1886         fd = open(file, O_RDONLY);
1887 #endif
1888         if (fd < 1) {
1889                 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
1890                         "Server: libwebsockets\x0d\x0a"
1891                         "\x0d\x0a"
1892                 );
1893                 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
1894                                                                 LWS_WRITE_HTTP);
1895
1896                 return -1;
1897         }
1898
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);
1905
1906         libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
1907
1908         n = 1;
1909         while (n > 0) {
1910                 n = read(fd, buf, 512);
1911                 if (n <= 0)
1912                         continue;
1913                 libwebsocket_write(wsi, (unsigned char *)buf, n,
1914                                                                 LWS_WRITE_HTTP);
1915         }
1916
1917         close(fd);
1918
1919         return 0;
1920 }
1921
1922
1923 /**
1924  * libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
1925  *                                            rx packet is complete
1926  * @wsi:                Websocket instance (available from user callback)
1927  *
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
1935  *  0.
1936  *
1937  *  Many protocols won't care becuse their packets are always small.
1938  */
1939
1940 size_t
1941 libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
1942 {
1943         return wsi->rx_packet_length;
1944 }