introduce-client-support.patch
[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         [WSI_TOKEN_GET_URI]     = { "GET ",                      4 },
26         [WSI_TOKEN_HOST]        = { "Host:",                     5 },
27         [WSI_TOKEN_CONNECTION]  = { "Connection:",              11 },
28         [WSI_TOKEN_KEY1]        = { "Sec-WebSocket-Key1:",      19 },
29         [WSI_TOKEN_KEY2]        = { "Sec-WebSocket-Key2:",      19 },
30         [WSI_TOKEN_PROTOCOL]    = { "Sec-WebSocket-Protocol:",  23 },
31         [WSI_TOKEN_UPGRADE]     = { "Upgrade:",                  8 },
32         [WSI_TOKEN_ORIGIN]      = { "Origin:",                   7 },
33         [WSI_TOKEN_DRAFT]       = { "Sec-WebSocket-Draft:",     20 },
34         [WSI_TOKEN_CHALLENGE]   = { "\x0d\x0a",                  2 },
35
36         [WSI_TOKEN_KEY]         = { "Sec-WebSocket-Key:",       18 },
37         [WSI_TOKEN_VERSION]     = { "Sec-WebSocket-Version:",   22 },
38
39         [WSI_TOKEN_ACCEPT]      = { "Sec-WebSocket-Accept:",    21 },
40         [WSI_TOKEN_NONCE]       = { "Sec-WebSocket-Nonce:",     20 },
41         [WSI_TOKEN_HTTP]        = { "HTTP/1.1 ",                 9 },
42         [WSI_TOKEN_SWORIGIN]    = { "Sec-WebSocket-Origin:",    21 },
43
44 };
45
46 int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
47 {
48         int n;
49
50         switch (wsi->parser_state) {
51         case WSI_TOKEN_GET_URI:
52         case WSI_TOKEN_HOST:
53         case WSI_TOKEN_CONNECTION:
54         case WSI_TOKEN_KEY1:
55         case WSI_TOKEN_KEY2:
56         case WSI_TOKEN_PROTOCOL:
57         case WSI_TOKEN_UPGRADE:
58         case WSI_TOKEN_ORIGIN:
59         case WSI_TOKEN_SWORIGIN:
60         case WSI_TOKEN_DRAFT:
61         case WSI_TOKEN_CHALLENGE:
62         case WSI_TOKEN_KEY:
63         case WSI_TOKEN_VERSION:
64         case WSI_TOKEN_ACCEPT:
65         case WSI_TOKEN_NONCE:
66         case WSI_TOKEN_HTTP:
67                 debug("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c);
68
69                 /* collect into malloc'd buffers */
70                 /* optional space swallow */
71                 if (!wsi->utf8_token[wsi->parser_state].token_len && c == ' ')
72                         break;
73
74                 /* special case space terminator for get-uri */
75                 if (wsi->parser_state == WSI_TOKEN_GET_URI && c == ' ') {
76                         wsi->utf8_token[wsi->parser_state].token[
77                            wsi->utf8_token[wsi->parser_state].token_len] = '\0';
78                         wsi->parser_state = WSI_TOKEN_SKIPPING;
79                         break;
80                 }
81
82                 /* allocate appropriate memory */
83                 if (wsi->utf8_token[wsi->parser_state].token_len ==
84                                                    wsi->current_alloc_len - 1) {
85                         /* need to extend */
86                         wsi->current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
87                         if (wsi->current_alloc_len >= LWS_MAX_HEADER_LEN) {
88                                 /* it's waaay to much payload, fail it */
89                                 strcpy(wsi->utf8_token[wsi->parser_state].token,
90                                    "!!! Length exceeded maximum supported !!!");
91                                 wsi->parser_state = WSI_TOKEN_SKIPPING;
92                                 break;
93                         }
94                         wsi->utf8_token[wsi->parser_state].token =
95                                realloc(wsi->utf8_token[wsi->parser_state].token,
96                                                         wsi->current_alloc_len);
97                 }
98
99                 /* bail at EOL */
100                 if (wsi->parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
101                         wsi->utf8_token[wsi->parser_state].token[
102                            wsi->utf8_token[wsi->parser_state].token_len] = '\0';
103                         wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
104                         break;
105                 }
106
107                 wsi->utf8_token[wsi->parser_state].token[
108                             wsi->utf8_token[wsi->parser_state].token_len++] = c;
109
110                 /* per-protocol end of headers management */
111
112                 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
113                         break;
114
115                 /* -76 has no version header */
116                 if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
117                               wsi->utf8_token[wsi->parser_state].token_len != 8)
118                         break;
119
120                 /* <= 03 has old handshake with version header */
121                 if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
122                          atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) < 4 &&
123                               wsi->utf8_token[wsi->parser_state].token_len != 8)
124                         break;
125
126                 /* For any supported protocol we have enough payload */
127
128                 debug("Setting WSI_PARSING_COMPLETE\n");
129                 wsi->parser_state = WSI_PARSING_COMPLETE;
130                 break;
131
132                 /* collecting and checking a name part */
133         case WSI_TOKEN_NAME_PART:
134                 debug("WSI_TOKEN_NAME_PART '%c'\n", c);
135
136                 if (wsi->name_buffer_pos == sizeof(wsi->name_buffer) - 1) {
137                         /* name bigger than we can handle, skip until next */
138                         wsi->parser_state = WSI_TOKEN_SKIPPING;
139                         break;
140                 }
141                 wsi->name_buffer[wsi->name_buffer_pos++] = c;
142                 wsi->name_buffer[wsi->name_buffer_pos] = '\0';
143
144                 for (n = 0; n < WSI_TOKEN_COUNT; n++) {
145                         if (wsi->name_buffer_pos != lws_tokens[n].token_len)
146                                 continue;
147                         if (strcmp(lws_tokens[n].token, wsi->name_buffer))
148                                 continue;
149                         debug("known hdr '%s'\n", wsi->name_buffer);
150                         wsi->parser_state = WSI_TOKEN_GET_URI + n;
151                         wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
152                         
153                         wsi->utf8_token[wsi->parser_state].token =
154                                                  malloc(wsi->current_alloc_len);
155                         wsi->utf8_token[wsi->parser_state].token_len = 0;
156                         n = WSI_TOKEN_COUNT;
157                 }
158
159                 /* colon delimiter means we just don't know this name */
160
161                 if (wsi->parser_state == WSI_TOKEN_NAME_PART && c == ':') {
162                         debug("skipping unknown header '%s'\n",
163                                                               wsi->name_buffer);
164                         wsi->parser_state = WSI_TOKEN_SKIPPING;
165                         break;
166                 }
167
168                 if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
169                         break;
170
171                 /* don't look for payload when it can just be http headers */
172
173                 if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len) {
174                         /* they're HTTP headers, not websocket upgrade! */
175                         debug("Setting WSI_PARSING_COMPLETE "
176                                                          "from http headers\n");
177                         wsi->parser_state = WSI_PARSING_COMPLETE;
178                 }
179
180                 /* 04 version has no packet content after end of hdrs */
181
182                 if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
183                          atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) >= 4) {
184                         debug("04 header completed\n");
185                         wsi->parser_state = WSI_PARSING_COMPLETE;
186                 }
187
188                 /* client parser? */
189
190                 if (wsi->ietf_spec_revision >= 4) {
191                         debug("04 header completed\n");
192                         wsi->parser_state = WSI_PARSING_COMPLETE;
193                 }
194
195                 break;
196
197                 /* skipping arg part of a name we didn't recognize */
198         case WSI_TOKEN_SKIPPING:
199                 debug("WSI_TOKEN_SKIPPING '%c'\n", c);
200                 if (c == '\x0d')
201                         wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
202                 break;
203         case WSI_TOKEN_SKIPPING_SAW_CR:
204                 debug("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
205                 if (c == '\x0a')
206                         wsi->parser_state = WSI_TOKEN_NAME_PART;
207                 else
208                         wsi->parser_state = WSI_TOKEN_SKIPPING;
209                 wsi->name_buffer_pos = 0;
210                 break;
211                 /* we're done, ignore anything else */
212         case WSI_PARSING_COMPLETE:
213                 debug("WSI_PARSING_COMPLETE '%c'\n", c);
214                 break;
215
216         default:        /* keep gcc happy */
217                 break;
218         }
219
220         return 0;
221 }
222
223 static unsigned char inline
224 xor_mask(struct libwebsocket *wsi, unsigned char c)
225 {
226         c ^= wsi->masking_key_04[wsi->frame_mask_index++];
227         if (wsi->frame_mask_index == 20)
228                 wsi->frame_mask_index = 0;
229
230         return c;
231 }
232
233
234 static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
235 {
236         int n;
237         unsigned char buf[20 + 4];
238
239         switch (wsi->lws_rx_parse_state) {
240         case LWS_RXPS_NEW:
241
242                 switch (wsi->ietf_spec_revision) {
243                 /* Firefox 4.0b6 likes this as of 30 Oct */
244                 case 0:
245                         if (c == 0xff)
246                                 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
247                         if (c == 0) {
248                                 wsi->lws_rx_parse_state =
249                                                        LWS_RXPS_EAT_UNTIL_76_FF;
250                                 wsi->rx_user_buffer_head = 0;
251                         }
252                         break;
253                 case 4:
254                         wsi->frame_masking_nonce_04[0] = c;
255                         wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_1;
256                         break;
257                 }
258                 break;
259         case LWS_RXPS_04_MASK_NONCE_1:
260                 wsi->frame_masking_nonce_04[1] = c;
261                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
262                 break;
263         case LWS_RXPS_04_MASK_NONCE_2:
264                 wsi->frame_masking_nonce_04[2] = c;
265                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
266                 break;
267         case LWS_RXPS_04_MASK_NONCE_3:
268                 wsi->frame_masking_nonce_04[3] = c;
269
270                 /*
271                  * we are able to compute the frame key now
272                  * it's a SHA1 of ( frame nonce we were just sent, concatenated
273                  * with the connection masking key we computed at handshake
274                  * time ) -- yeah every frame from the client invokes a SHA1
275                  * for no real reason so much for lightweight.
276                  */
277
278                 buf[0] = wsi->frame_masking_nonce_04[0];
279                 buf[1] = wsi->frame_masking_nonce_04[1];
280                 buf[2] = wsi->frame_masking_nonce_04[2];
281                 buf[3] = wsi->frame_masking_nonce_04[3];
282
283                 memcpy(buf + 4, wsi->masking_key_04, 20);
284
285                 /*
286                  * wsi->frame_mask_04 will be our recirculating 20-byte XOR key
287                  * for this frame
288                  */
289         
290                 SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
291
292                 /*
293                  * start from the zero'th byte in the XOR key buffer since
294                  * this is the start of a frame with a new key
295                  */
296
297                 wsi->frame_mask_index = 0;
298                 
299                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
300                 break;
301
302         /*
303          *  04 logical framing from the spec (all this is masked when incoming
304          *  and has to be unmasked)
305          *
306          * We ignore the possibility of extension data because we don't
307          * negotiate any extensions at the moment.
308          * 
309          *    0                   1                   2                   3
310          *    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
311          *   +-+-+-+-+-------+-+-------------+-------------------------------+
312          *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
313          *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
314          *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
315          *   | |1|2|3|       |4|             |                               |
316          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
317          *   |     Extended payload length continued, if payload len == 127  |
318          *   + - - - - - - - - - - - - - - - +-------------------------------+
319          *   |                               |         Extension data        |
320          *   +-------------------------------+ - - - - - - - - - - - - - - - +
321          *   :                                                               :
322          *   +---------------------------------------------------------------+
323          *   :                       Application data                        :
324          *   +---------------------------------------------------------------+
325          *
326          *  We pass payload through to userland as soon as we get it, ignoring
327          *  FIN.  It's up to userland to buffer it up if it wants to see a
328          *  whole unfragmented block of the original size (which may be up to
329          *  2^63 long!)
330          */
331
332         case LWS_RXPS_04_FRAME_HDR_1:
333                 /*
334                  * 04 spec defines the opcode like this: (1, 2, and 3 are
335                  * "control frame" opcodes which may not be fragmented or
336                  * have size larger than 126)
337                  * 
338                  *       frame-opcode           =
339                  *             %x0 ; continuation frame
340                  *           / %x1 ; connection close
341                  *           / %x2 ; ping
342                  *           / %x3 ; pong
343                  *           / %x4 ; text frame
344                  *           / %x5 ; binary frame
345                  *           / %x6-F ; reserved
346                  *
347                  *        FIN (b7)
348                  */
349
350                 c = xor_mask(wsi, c);
351
352                 if (c & 0x70) {
353                         fprintf(stderr, "Frame has extensions set illegally 1\n");
354                         /* kill the connection */
355                         return -1;
356                 }
357
358                 wsi->opcode = c & 0xf;
359                 wsi->final = !!((c >> 7) & 1);
360
361                 if (wsi->final &&
362                         wsi->opcode == LWS_WS_OPCODE_04__CONTINUATION &&
363                                                    wsi->rx_packet_length == 0) {
364                         fprintf(stderr,
365                                       "Frame starts with final continuation\n");
366                         /* kill the connection */
367                         return -1;
368                 }
369
370                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
371                 break;
372
373         case LWS_RXPS_04_FRAME_HDR_LEN:
374                 c = xor_mask(wsi, c);
375
376                 if (c & 0x80) {
377                         fprintf(stderr, "Frame has extensions "
378                                                            "set illegally 2\n");
379                         /* kill the connection */
380                         return -1;
381                 }
382
383                 switch (c) {
384                 case 126:
385                         /* control frames are not allowed to have big lengths */
386                         switch (wsi->opcode) {
387                         case LWS_WS_OPCODE_04__CLOSE:
388                         case LWS_WS_OPCODE_04__PING:
389                         case LWS_WS_OPCODE_04__PONG:
390                                 fprintf(stderr, "Control frame asking for "
391                                                 "extended length is illegal\n");
392                                 /* kill the connection */
393                                 return -1;
394                         default:
395                                 break;
396                         }
397                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
398                         break;
399                 case 127:
400                         /* control frames are not allowed to have big lengths */
401                         switch (wsi->opcode) {
402                         case LWS_WS_OPCODE_04__CLOSE:
403                         case LWS_WS_OPCODE_04__PING:
404                         case LWS_WS_OPCODE_04__PONG:
405                                 fprintf(stderr, "Control frame asking for "
406                                                 "extended length is illegal\n");
407                                 /* kill the connection */
408                                 return -1;
409                         default:
410                                 break;
411                         }
412                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
413                         break;
414                 default:
415 //                      fprintf(stderr, "seen incoming 04 frame len %d\n", c);
416                         wsi->rx_packet_length = c;
417                         wsi->lws_rx_parse_state =
418                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
419                         break;
420                 }
421                 break;
422
423         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
424                 c = xor_mask(wsi, c);
425
426                 wsi->rx_packet_length = c << 8;
427                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
428                 break;
429
430         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
431                 c = xor_mask(wsi, c);
432
433                 wsi->rx_packet_length |= c;
434                 wsi->lws_rx_parse_state =
435                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
436                 break;
437
438         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
439                 c = xor_mask(wsi, c);
440                 if (c & 0x80) {
441                         fprintf(stderr, "b63 of length must be zero\n");
442                         /* kill the connection */
443                         return -1;
444                 }
445                 wsi->rx_packet_length = ((size_t)c) << 56;
446                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
447                 break;
448
449         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
450                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 48;
451                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
452                 break;
453
454         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
455                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 40;
456                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
457                 break;
458
459         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
460                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 32;
461                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
462                 break;
463
464         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
465                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 24;
466                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
467                 break;
468
469         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
470                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 16;
471                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
472                 break;
473
474         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
475                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 8;
476                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
477                 break;
478
479         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
480                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c));
481                 wsi->lws_rx_parse_state =
482                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
483                 break;
484
485         case LWS_RXPS_EAT_UNTIL_76_FF:
486                 if (c == 0xff) {
487                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
488                         goto issue;
489                 }
490                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
491                                               (wsi->rx_user_buffer_head++)] = c;
492
493                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
494                         break;
495 issue:
496                 if (wsi->protocol->callback)
497                         wsi->protocol->callback(wsi, LWS_CALLBACK_RECEIVE,
498                           wsi->user_space,
499                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
500                           wsi->rx_user_buffer_head);
501                 wsi->rx_user_buffer_head = 0;
502                 break;
503         case LWS_RXPS_SEEN_76_FF:
504                 if (c)
505                         break;
506
507                 debug("Seen that client is requesting "
508                                 "a v76 close, sending ack\n");
509                 buf[0] = 0xff;
510                 buf[1] = 0;
511                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
512                 if (n < 0) {
513                         fprintf(stderr, "ERROR writing to socket");
514                         return -1;
515                 }
516                 debug("  v76 close ack sent, server closing skt\n");
517                 /* returning < 0 will get it closed in parent */
518                 return -1;
519
520         case LWS_RXPS_PULLING_76_LENGTH:
521                 break;
522
523         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
524                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
525                                (wsi->rx_user_buffer_head++)] = xor_mask(wsi, c);
526
527                 if (--wsi->rx_packet_length == 0) {
528                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
529                         goto spill;
530                 }
531                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
532                         break;
533 spill:
534                 /*
535                  * is this frame a control packet we should take care of at this
536                  * layer?  If so service it and hide it from the user callback
537                  */
538
539                 switch (wsi->opcode) {
540                 case LWS_WS_OPCODE_04__CLOSE:
541                         /* parrot the close packet payload back */
542                         n = libwebsocket_write(wsi, (unsigned char *)
543                            &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
544                                      wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
545                         /* close the connection */
546                         return -1;
547
548                 case LWS_WS_OPCODE_04__PING:
549                         /* parrot the ping packet payload back as a pong*/
550                         n = libwebsocket_write(wsi, (unsigned char *)
551                             &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
552                                     wsi->rx_user_buffer_head, LWS_WRITE_PONG);
553                         break;
554
555                 case LWS_WS_OPCODE_04__PONG:
556                         /* keep the statistics... */
557                         wsi->pings_vs_pongs--;
558                         /* ... then just drop it */
559                         wsi->rx_user_buffer_head = 0;
560                         return 0;
561
562                 default:
563                         break;
564                 }
565
566                 /*
567                  * No it's real payload, pass it up to the user callback.
568                  * It's nicely buffered with the pre-padding taken care of
569                  * so it can be sent straight out again using libwebsocket_write
570                  */
571
572                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
573                                                wsi->rx_user_buffer_head] = '\0';
574
575                 if (wsi->protocol->callback)
576                         wsi->protocol->callback(wsi, LWS_CALLBACK_RECEIVE,
577                                                 wsi->user_space,
578                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
579                                                       wsi->rx_user_buffer_head);
580                 wsi->rx_user_buffer_head = 0;
581                 break;
582         }
583
584         return 0;
585 }
586
587
588 int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
589 {
590         int n;
591         unsigned char buf[20 + 4];
592
593         switch (wsi->lws_rx_parse_state) {
594         case LWS_RXPS_NEW:
595
596                 switch (wsi->ietf_spec_revision) {
597                 /* Firefox 4.0b6 likes this as of 30 Oct */
598                 case 0:
599                         if (c == 0xff)
600                                 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
601                         if (c == 0) {
602                                 wsi->lws_rx_parse_state =
603                                                        LWS_RXPS_EAT_UNTIL_76_FF;
604                                 wsi->rx_user_buffer_head = 0;
605                         }
606                         break;
607                 case 4:
608                 /*
609                  *  04 logical framing from the spec (all this is masked when incoming
610                  *  and has to be unmasked)
611                  *
612                  * We ignore the possibility of extension data because we don't
613                  * negotiate any extensions at the moment.
614                  * 
615                  *    0                   1                   2                   3
616                  *    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
617                  *   +-+-+-+-+-------+-+-------------+-------------------------------+
618                  *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
619                  *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
620                  *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
621                  *   | |1|2|3|       |4|             |                               |
622                  *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
623                  *   |     Extended payload length continued, if payload len == 127  |
624                  *   + - - - - - - - - - - - - - - - +-------------------------------+
625                  *   |                               |         Extension data        |
626                  *   +-------------------------------+ - - - - - - - - - - - - - - - +
627                  *   :                                                               :
628                  *   +---------------------------------------------------------------+
629                  *   :                       Application data                        :
630                  *   +---------------------------------------------------------------+
631                  *
632                  *  We pass payload through to userland as soon as we get it, ignoring
633                  *  FIN.  It's up to userland to buffer it up if it wants to see a
634                  *  whole unfragmented block of the original size (which may be up to
635                  *  2^63 long!)
636                  */
637
638                 /*
639                  * 04 spec defines the opcode like this: (1, 2, and 3 are
640                  * "control frame" opcodes which may not be fragmented or
641                  * have size larger than 126)
642                  * 
643                  *       frame-opcode           =
644                  *             %x0 ; continuation frame
645                  *           / %x1 ; connection close
646                  *           / %x2 ; ping
647                  *           / %x3 ; pong
648                  *           / %x4 ; text frame
649                  *           / %x5 ; binary frame
650                  *           / %x6-F ; reserved
651                  *
652                  *        FIN (b7)
653                  */
654
655                         if (c & 0x70) {
656                                 fprintf(stderr, "Frame has extensions set "
657                                    "illegally on first framing byte %02X\n", c);
658                                 /* kill the connection */
659                                 return -1;
660                         }
661
662                         wsi->opcode = c & 0xf;
663                         wsi->final = !!((c >> 7) & 1);
664
665                         if (wsi->final &&
666                             wsi->opcode == LWS_WS_OPCODE_04__CONTINUATION &&
667                                                    wsi->rx_packet_length == 0) {
668                                 fprintf(stderr,
669                                       "Frame starts with final continuation\n");
670                                 /* kill the connection */
671                                 return -1;
672                         }
673
674                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
675                         break;
676                 }
677                 break;
678
679
680         case LWS_RXPS_04_FRAME_HDR_LEN:
681
682                 if (c & 0x80) {
683                         fprintf(stderr,
684                                       "Frame has extensions set illegally 4\n");
685                         /* kill the connection */
686                         return -1;
687                 }
688
689                 switch (c) {
690                 case 126:
691                         /* control frames are not allowed to have big lengths */
692                         switch (wsi->opcode) {
693                         case LWS_WS_OPCODE_04__CLOSE:
694                         case LWS_WS_OPCODE_04__PING:
695                         case LWS_WS_OPCODE_04__PONG:
696                                 fprintf(stderr, "Control frame asking for "
697                                                 "extended length is illegal\n");
698                                 /* kill the connection */
699                                 return -1;
700                         default:
701                                 break;
702                         }
703                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
704                         break;
705                 case 127:
706                         /* control frames are not allowed to have big lengths */
707                         switch (wsi->opcode) {
708                         case LWS_WS_OPCODE_04__CLOSE:
709                         case LWS_WS_OPCODE_04__PING:
710                         case LWS_WS_OPCODE_04__PONG:
711                                 fprintf(stderr, "Control frame asking for "
712                                                 "extended length is illegal\n");
713                                 /* kill the connection */
714                                 return -1;
715                         default:
716                                 break;
717                         }
718                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
719                         break;
720                 default:
721                         wsi->rx_packet_length = c;
722                         wsi->lws_rx_parse_state =
723                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
724                         break;
725                 }
726                 break;
727
728         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
729                 wsi->rx_packet_length = c << 8;
730                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
731                 break;
732
733         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
734                 wsi->rx_packet_length |= c;
735                 wsi->lws_rx_parse_state =
736                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
737                 break;
738
739         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
740                 if (c & 0x80) {
741                         fprintf(stderr, "b63 of length must be zero\n");
742                         /* kill the connection */
743                         return -1;
744                 }
745                 wsi->rx_packet_length = ((size_t)c) << 56;
746                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
747                 break;
748
749         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
750                 wsi->rx_packet_length |= ((size_t)c) << 48;
751                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
752                 break;
753
754         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
755                 wsi->rx_packet_length |= ((size_t)c) << 40;
756                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
757                 break;
758
759         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
760                 wsi->rx_packet_length |= ((size_t)c) << 32;
761                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
762                 break;
763
764         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
765                 wsi->rx_packet_length |= ((size_t)c) << 24;
766                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
767                 break;
768
769         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
770                 wsi->rx_packet_length |= ((size_t)c) << 16;
771                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
772                 break;
773
774         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
775                 wsi->rx_packet_length |= ((size_t)c) << 8;
776                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
777                 break;
778
779         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
780                 wsi->rx_packet_length |= (size_t)c;
781                 wsi->lws_rx_parse_state =
782                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
783                 break;
784
785         case LWS_RXPS_EAT_UNTIL_76_FF:
786                 if (c == 0xff) {
787                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
788                         goto issue;
789                 }
790                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
791                                               (wsi->rx_user_buffer_head++)] = c;
792
793                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
794                         break;
795 issue:
796                 if (wsi->protocol->callback)
797                         wsi->protocol->callback(wsi,
798                                                 LWS_CALLBACK_CLIENT_RECEIVE,
799                                                 wsi->user_space,
800                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
801                                                       wsi->rx_user_buffer_head);
802                 wsi->rx_user_buffer_head = 0;
803                 break;
804         case LWS_RXPS_SEEN_76_FF:
805                 if (c)
806                         break;
807
808                 debug("Seen that client is requesting "
809                                 "a v76 close, sending ack\n");
810                 buf[0] = 0xff;
811                 buf[1] = 0;
812                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
813                 if (n < 0) {
814                         fprintf(stderr, "ERROR writing to socket");
815                         return -1;
816                 }
817                 debug("  v76 close ack sent, server closing skt\n");
818                 /* returning < 0 will get it closed in parent */
819                 return -1;
820
821         case LWS_RXPS_PULLING_76_LENGTH:
822                 break;
823
824         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
825                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
826                                  (wsi->rx_user_buffer_head++)] = c;
827                 if (--wsi->rx_packet_length == 0) {
828                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
829                         goto spill;
830                 }
831                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
832                         break;
833 spill:
834                 /*
835                  * is this frame a control packet we should take care of at this
836                  * layer?  If so service it and hide it from the user callback
837                  */
838
839                 switch (wsi->opcode) {
840                 case LWS_WS_OPCODE_04__CLOSE:
841                         /* parrot the close packet payload back */
842                         n = libwebsocket_write(wsi, (unsigned char *)
843                            &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
844                                      wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
845                         /* close the connection */
846                         return -1;
847
848                 case LWS_WS_OPCODE_04__PING:
849                         /* parrot the ping packet payload back as a pong*/
850                         n = libwebsocket_write(wsi, (unsigned char *)
851                             &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
852                                     wsi->rx_user_buffer_head, LWS_WRITE_PONG);
853                         break;
854
855                 case LWS_WS_OPCODE_04__PONG:
856                         /* keep the statistics... */
857                         wsi->pings_vs_pongs--;
858                         /* ... then just drop it */
859                         wsi->rx_user_buffer_head = 0;
860                         return 0;
861
862                 default:
863                         break;
864                 }
865
866                 /*
867                  * No it's real payload, pass it up to the user callback.
868                  * It's nicely buffered with the pre-padding taken care of
869                  * so it can be sent straight out again using libwebsocket_write
870                  */
871
872                 if (wsi->protocol->callback)
873                         wsi->protocol->callback(wsi,
874                                                 LWS_CALLBACK_CLIENT_RECEIVE,
875                                                 wsi->user_space,
876                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
877                                                       wsi->rx_user_buffer_head);
878                 wsi->rx_user_buffer_head = 0;
879                 break;
880         default:
881                 fprintf(stderr, "client rx illegal state\n");
882                 return 1;
883         }
884
885         return 0;
886 }
887
888
889
890 int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
891                                                  unsigned char *buf, size_t len)
892 {
893         int n;
894
895 #ifdef DEBUG
896         fprintf(stderr, "received %d byte packet\n", (int)len);
897         for (n = 0; n < len; n++)
898                 fprintf(stderr, "%02X ", buf[n]);
899         fprintf(stderr, "\n");
900 #endif
901
902         /* let the rx protocol state machine have as much as it needs */
903
904         n = 0;
905         while (n < len)
906                 if (libwebsocket_rx_sm(wsi, buf[n++]) < 0)
907                         return -1;
908
909         return 0;
910 }
911
912
913 static int
914 libwebsocket_04_frame_mask_generate(struct libwebsocket *wsi)
915 {
916         int fd;
917         char buf[4 + 20];
918         int n;
919
920         /* fetch the per-frame nonce */
921
922         fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
923         if (fd < 1) {
924                 fprintf(stderr, "Unable to open random device %s\n",
925                                                         SYSTEM_RANDOM_FILEPATH);
926                 return 1;
927         }
928         n = read(fd, wsi->frame_masking_nonce_04, 4);
929         if (n != 4) {
930                 fprintf(stderr, "Unable to read from random device %s %d\n",
931                                                      SYSTEM_RANDOM_FILEPATH, n);
932                 return 1;
933         }
934         close(fd);
935
936         /*
937          * the frame key is the frame nonce (4 bytes) followed by the
938          * connection masking key, hashed by SHA1
939          */
940
941         memcpy(buf, wsi->frame_masking_nonce_04, 4);
942         memcpy(buf + 4, wsi->masking_key_04, 20);
943
944         /* concatenate the nonce with the connection key then hash it */
945
946         SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
947
948         /* start masking from first byte of masking key buffer */
949         wsi->frame_mask_index = 0;
950
951         return 0;
952 }
953
954
955 /**
956  * libwebsocket_write() - Apply protocol then write data to client
957  * @wsi:        Websocket instance (available from user callback)
958  * @buf:        The data to send.  For data being sent on a websocket
959  *              connection (ie, not default http), this buffer MUST have
960  *              LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
961  *              and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
962  *              in the buffer after (buf + len).  This is so the protocol
963  *              header and trailer data can be added in-situ.
964  * @len:        Count of the data bytes in the payload starting from buf
965  * @protocol:   Use LWS_WRITE_HTTP to reply to an http connection, and one
966  *              of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
967  *              data on a websockets connection.  Remember to allow the extra
968  *              bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
969  *              are used.
970  *
971  *      This function provides the way to issue data back to the client
972  *      for both http and websocket protocols.
973  *
974  *      In the case of sending using websocket protocol, be sure to allocate
975  *      valid storage before and after buf as explained above.  This scheme
976  *      allows maximum efficiency of sending data and protocol in a single
977  *      packet while not burdening the user code with any protocol knowledge.
978  */
979
980  /* FIXME FIN bit */
981
982 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
983                           size_t len, enum libwebsocket_write_protocol protocol)
984 {
985         int n;
986         int pre = 0;
987         int post = 0;
988         unsigned int shift = 7;
989
990         if (protocol == LWS_WRITE_HTTP)
991                 goto send_raw;
992
993         /* websocket protocol, either binary or text */
994
995         if (wsi->state != WSI_STATE_ESTABLISHED)
996                 return -1;
997
998         switch (wsi->ietf_spec_revision) {
999         /* chrome likes this as of 30 Oct */
1000         /* Firefox 4.0b6 likes this as of 30 Oct */
1001         case 0:
1002                 if (protocol == LWS_WRITE_BINARY) {
1003                         /* in binary mode we send 7-bit used length blocks */
1004                         pre = 1;
1005                         while (len & (127 << shift)) {
1006                                 pre++;
1007                                 shift += 7;
1008                         }
1009                         n = 0;
1010                         shift -= 7;
1011                         while (shift >= 0) {
1012                                 if (shift)
1013                                         buf[0 - pre + n] =
1014                                                   ((len >> shift) & 127) | 0x80;
1015                                 else
1016                                         buf[0 - pre + n] =
1017                                                   ((len >> shift) & 127);
1018                                 n++;
1019                                 shift -= 7;
1020                         }
1021                         break;
1022                 }
1023
1024                 /* frame type = text, length-free spam mode */
1025
1026                 buf[-1] = 0;
1027                 buf[len] = 0xff; /* EOT marker */
1028                 pre = 1;
1029                 post = 1;
1030                 break;
1031
1032         case 4:
1033
1034                 switch (protocol) {
1035                 case LWS_WRITE_TEXT:
1036                         n = LWS_WS_OPCODE_04__TEXT_FRAME;
1037                         break;
1038                 case LWS_WRITE_BINARY:
1039                         n = LWS_WS_OPCODE_04__BINARY_FRAME;
1040                         break;
1041                 case LWS_WRITE_CLOSE:
1042                         n = LWS_WS_OPCODE_04__CLOSE;
1043                         break;
1044                 case LWS_WRITE_PING:
1045                         n = LWS_WS_OPCODE_04__PING;
1046                         wsi->pings_vs_pongs++;
1047                         break;
1048                 case LWS_WRITE_PONG:
1049                         n = LWS_WS_OPCODE_04__PONG;
1050                         break;
1051                 default:
1052                         fprintf(stderr, "libwebsocket_write: unknown write "
1053                                                          "opcode / protocol\n");
1054                         return -1;
1055                 }
1056
1057                 /*
1058                  * We don't really support the metaframe concept with FIN.
1059                  * Just set FIN on every packet for now
1060                  */
1061
1062                 n |= 1 << 7;
1063
1064                 if (len < 126) {
1065                         buf[-2] = n;
1066                         buf[-1] = len;
1067                         pre = 2;
1068                 } else {
1069                         if (len < 65536) {
1070                                 buf[-4] = n;
1071                                 buf[-3] = 126;
1072                                 buf[-2] = len >> 8;
1073                                 buf[-1] = len;
1074                                 pre = 4;
1075                         } else {
1076                                 buf[-10] = n;
1077                                 buf[-9] = 127;
1078 #if defined __LP64__
1079                                         buf[-8] = (len >> 56) & 0x7f;
1080                                         buf[-7] = len >> 48;
1081                                         buf[-6] = len >> 40;
1082                                         buf[-5] = len >> 32;
1083 #else
1084                                         buf[-8] = 0;
1085                                         buf[-7] = 0;
1086                                         buf[-6] = 0;
1087                                         buf[-5] = 0;
1088 #endif
1089                                 buf[-4] = len >> 24;
1090                                 buf[-3] = len >> 16;
1091                                 buf[-2] = len >> 8;
1092                                 buf[-1] = len;
1093                                 pre = 10;
1094                         }
1095                 }
1096                 break;
1097         }
1098
1099 #if 0
1100         for (n = 0; n < (len + pre + post); n++)
1101                 fprintf(stderr, "%02X ", buf[n - pre]);
1102
1103         fprintf(stderr, "\n");
1104 #endif
1105
1106         /*
1107          * Deal with masking if appropriate
1108          */
1109
1110         if (wsi->client_mode && wsi->ietf_spec_revision == 4) {
1111
1112                 if (libwebsocket_04_frame_mask_generate(wsi)) {
1113                         fprintf(stderr, "libwebsocket_write: "
1114                                               "frame mask generation failed\n");
1115                         return 1;
1116                 }
1117
1118                 /*
1119                  * use the XOR masking against everything we send
1120                  * past the frame nonce
1121                  */
1122
1123                 for (n = 0; n < (len + pre + post); n++)
1124                         buf[n - pre] = xor_mask(wsi, buf[n - pre]);
1125
1126                 /* make space for the frame nonce in clear */
1127                 pre += 4;
1128
1129                 /* copy the frame nonce into place */
1130                 memcpy(&buf[0 - pre], wsi->frame_masking_nonce_04, 4);
1131         }
1132
1133
1134 send_raw:
1135 #ifdef LWS_OPENSSL_SUPPORT
1136         if (use_ssl) {
1137                 n = SSL_write(wsi->ssl, buf - pre, len + pre + post);
1138                 if (n < 0) {
1139                         fprintf(stderr, "ERROR writing to socket");
1140                         return -1;
1141                 }
1142         } else {
1143 #endif
1144                 n = send(wsi->sock, buf - pre, len + pre + post, 0);
1145                 if (n < 0) {
1146                         fprintf(stderr, "ERROR writing to socket");
1147                         return -1;
1148                 }
1149 #ifdef LWS_OPENSSL_SUPPORT
1150         }
1151 #endif
1152         debug("written %d bytes to client\n", (int)len);
1153
1154         return 0;
1155 }
1156
1157
1158 /**
1159  * libwebsockets_serve_http_file() - Send a file back to the client using http
1160  * @wsi:                Websocket instance (available from user callback)
1161  * @file:               The file to issue over http
1162  * @content_type:       The http content type, eg, text/html
1163  *
1164  *      This function is intended to be called from the callback in response
1165  *      to http requests from the client.  It allows the callback to issue
1166  *      local files down the http link in a single step.
1167  */
1168
1169 int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
1170                                                        const char *content_type)
1171 {
1172         int fd;
1173         struct stat stat;
1174         char buf[512];
1175         char *p = buf;
1176         int n;
1177
1178         fd = open(file, O_RDONLY);
1179         if (fd < 1) {
1180                 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
1181                         "Server: libwebsockets\x0d\x0a"
1182                         "\x0d\x0a"
1183                 );
1184                 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
1185                                                                 LWS_WRITE_HTTP);
1186
1187                 return -1;
1188         }
1189
1190         fstat(fd, &stat);
1191         p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
1192                         "Server: libwebsockets\x0d\x0a"
1193                         "Content-Type: %s\x0d\x0a"
1194                         "Content-Length: %u\x0d\x0a"
1195                         "\x0d\x0a", content_type, (unsigned int)stat.st_size);
1196
1197         libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
1198
1199         n = 1;
1200         while (n > 0) {
1201                 n = read(fd, buf, 512);
1202                 libwebsocket_write(wsi, (unsigned char *)buf, n,
1203                                                                 LWS_WRITE_HTTP);
1204         }
1205
1206         close(fd);
1207
1208         return 0;
1209 }
1210
1211
1212 /**
1213  * libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
1214  *                                            rx packet is complete
1215  * @wsi:                Websocket instance (available from user callback)
1216  *
1217  *      This function is intended to be called from the callback if the
1218  *  user code is interested in "complete packets" from the client.
1219  *  libwebsockets just passes through payload as it comes and issues a buffer
1220  *  additionally when it hits a built-in limit.  The LWS_CALLBACK_RECEIVE
1221  *  callback handler can use this API to find out if the buffer it has just
1222  *  been given is the last piece of a "complete packet" from the client --
1223  *  when that is the case libwebsockets_remaining_packet_payload() will return
1224  *  0.
1225  *
1226  *  Many protocols won't care becuse their packets are always small.
1227  */
1228
1229 size_t
1230 libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
1231 {
1232         return wsi->rx_packet_length;
1233 }