workaround-32bit-size_t.patch
[platform/upstream/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 inline unsigned char
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,
354                                       "Frame has extensions set illegally 1\n");
355                         /* kill the connection */
356                         return -1;
357                 }
358
359                 wsi->opcode = c & 0xf;
360                 wsi->final = !!((c >> 7) & 1);
361
362                 if (wsi->final &&
363                         wsi->opcode == LWS_WS_OPCODE_04__CONTINUATION &&
364                                                    wsi->rx_packet_length == 0) {
365                         fprintf(stderr,
366                                       "Frame starts with final continuation\n");
367                         /* kill the connection */
368                         return -1;
369                 }
370
371                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
372                 break;
373
374         case LWS_RXPS_04_FRAME_HDR_LEN:
375                 c = xor_mask(wsi, c);
376
377                 if (c & 0x80) {
378                         fprintf(stderr, "Frame has extensions "
379                                                            "set illegally 2\n");
380                         /* kill the connection */
381                         return -1;
382                 }
383
384                 switch (c) {
385                 case 126:
386                         /* control frames are not allowed to have big lengths */
387                         switch (wsi->opcode) {
388                         case LWS_WS_OPCODE_04__CLOSE:
389                         case LWS_WS_OPCODE_04__PING:
390                         case LWS_WS_OPCODE_04__PONG:
391                                 fprintf(stderr, "Control frame asking for "
392                                                 "extended length is illegal\n");
393                                 /* kill the connection */
394                                 return -1;
395                         default:
396                                 break;
397                         }
398                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
399                         break;
400                 case 127:
401                         /* control frames are not allowed to have big lengths */
402                         switch (wsi->opcode) {
403                         case LWS_WS_OPCODE_04__CLOSE:
404                         case LWS_WS_OPCODE_04__PING:
405                         case LWS_WS_OPCODE_04__PONG:
406                                 fprintf(stderr, "Control frame asking for "
407                                                 "extended length is illegal\n");
408                                 /* kill the connection */
409                                 return -1;
410                         default:
411                                 break;
412                         }
413                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
414                         break;
415                 default:
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 #if defined __LP64__
446                 wsi->rx_packet_length = ((size_t)c) << 56;
447 #else
448                 wsi->rx_packet_length = 0;
449 #endif
450                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
451                 break;
452
453         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
454 #if defined __LP64__
455                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 48;
456 #endif
457                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
458                 break;
459
460         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
461 #if defined __LP64__
462                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 40;
463 #endif
464                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
465                 break;
466
467         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
468 #if defined __LP64__
469                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 32;
470 #endif
471                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
472                 break;
473
474         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
475                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 24;
476                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
477                 break;
478
479         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
480                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 16;
481                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
482                 break;
483
484         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
485                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c)) << 8;
486                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
487                 break;
488
489         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
490                 wsi->rx_packet_length |= ((size_t)xor_mask(wsi, c));
491                 wsi->lws_rx_parse_state =
492                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
493                 break;
494
495         case LWS_RXPS_EAT_UNTIL_76_FF:
496                 if (c == 0xff) {
497                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
498                         goto issue;
499                 }
500                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
501                                               (wsi->rx_user_buffer_head++)] = c;
502
503                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
504                         break;
505 issue:
506                 if (wsi->protocol->callback)
507                         wsi->protocol->callback(wsi, LWS_CALLBACK_RECEIVE,
508                           wsi->user_space,
509                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
510                           wsi->rx_user_buffer_head);
511                 wsi->rx_user_buffer_head = 0;
512                 break;
513         case LWS_RXPS_SEEN_76_FF:
514                 if (c)
515                         break;
516
517                 debug("Seen that client is requesting "
518                                 "a v76 close, sending ack\n");
519                 buf[0] = 0xff;
520                 buf[1] = 0;
521                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
522                 if (n < 0) {
523                         fprintf(stderr, "ERROR writing to socket");
524                         return -1;
525                 }
526                 debug("  v76 close ack sent, server closing skt\n");
527                 /* returning < 0 will get it closed in parent */
528                 return -1;
529
530         case LWS_RXPS_PULLING_76_LENGTH:
531                 break;
532
533         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
534                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
535                                (wsi->rx_user_buffer_head++)] = xor_mask(wsi, c);
536
537                 if (--wsi->rx_packet_length == 0) {
538                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
539                         goto spill;
540                 }
541                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
542                         break;
543 spill:
544                 /*
545                  * is this frame a control packet we should take care of at this
546                  * layer?  If so service it and hide it from the user callback
547                  */
548
549                 switch (wsi->opcode) {
550                 case LWS_WS_OPCODE_04__CLOSE:
551                         /* parrot the close packet payload back */
552                         n = libwebsocket_write(wsi, (unsigned char *)
553                            &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
554                                      wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
555                         /* close the connection */
556                         return -1;
557
558                 case LWS_WS_OPCODE_04__PING:
559                         /* parrot the ping packet payload back as a pong*/
560                         n = libwebsocket_write(wsi, (unsigned char *)
561                             &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
562                                     wsi->rx_user_buffer_head, LWS_WRITE_PONG);
563                         break;
564
565                 case LWS_WS_OPCODE_04__PONG:
566                         /* keep the statistics... */
567                         wsi->pings_vs_pongs--;
568                         /* ... then just drop it */
569                         wsi->rx_user_buffer_head = 0;
570                         return 0;
571
572                 default:
573                         break;
574                 }
575
576                 /*
577                  * No it's real payload, pass it up to the user callback.
578                  * It's nicely buffered with the pre-padding taken care of
579                  * so it can be sent straight out again using libwebsocket_write
580                  */
581
582                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
583                                                wsi->rx_user_buffer_head] = '\0';
584
585                 if (wsi->protocol->callback)
586                         wsi->protocol->callback(wsi, LWS_CALLBACK_RECEIVE,
587                                                 wsi->user_space,
588                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
589                                                       wsi->rx_user_buffer_head);
590                 wsi->rx_user_buffer_head = 0;
591                 break;
592         }
593
594         return 0;
595 }
596
597
598 int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
599 {
600         int n;
601         unsigned char buf[20 + 4];
602
603         switch (wsi->lws_rx_parse_state) {
604         case LWS_RXPS_NEW:
605
606                 switch (wsi->ietf_spec_revision) {
607                 /* Firefox 4.0b6 likes this as of 30 Oct */
608                 case 0:
609                         if (c == 0xff)
610                                 wsi->lws_rx_parse_state = LWS_RXPS_SEEN_76_FF;
611                         if (c == 0) {
612                                 wsi->lws_rx_parse_state =
613                                                        LWS_RXPS_EAT_UNTIL_76_FF;
614                                 wsi->rx_user_buffer_head = 0;
615                         }
616                         break;
617                 case 4:
618         /*
619          *  04 logical framing from the spec (all this is masked when
620          *  incoming and has to be unmasked)
621          *
622          * We ignore the possibility of extension data because we don't
623          * negotiate any extensions at the moment.
624          *
625          *    0                   1                   2                   3
626          *    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
627          *   +-+-+-+-+-------+-+-------------+-------------------------------+
628          *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
629          *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
630          *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
631          *   | |1|2|3|       |4|             |                               |
632          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
633          *   |     Extended payload length continued, if payload len == 127  |
634          *   + - - - - - - - - - - - - - - - +-------------------------------+
635          *   |                               |         Extension data        |
636          *   +-------------------------------+ - - - - - - - - - - - - - - - +
637          *   :                                                               :
638          *   +---------------------------------------------------------------+
639          *   :                       Application data                        :
640          *   +---------------------------------------------------------------+
641          *
642          *  We pass payload through to userland as soon as we get it, ignoring
643          *  FIN.  It's up to userland to buffer it up if it wants to see a
644          *  whole unfragmented block of the original size (which may be up to
645          *  2^63 long!)
646          */
647
648                 /*
649                  * 04 spec defines the opcode like this: (1, 2, and 3 are
650                  * "control frame" opcodes which may not be fragmented or
651                  * have size larger than 126)
652                  *
653                  *       frame-opcode           =
654                  *                %x0 ; continuation frame
655                  *              / %x1 ; connection close
656                  *              / %x2 ; ping
657                  *              / %x3 ; pong
658                  *              / %x4 ; text frame
659                  *              / %x5 ; binary frame
660                  *              / %x6-F ; reserved
661                  *
662                  *              FIN (b7)
663                  */
664
665                         if (c & 0x70) {
666                                 fprintf(stderr, "Frame has extensions set "
667                                    "illegally on first framing byte %02X\n", c);
668                                 /* kill the connection */
669                                 return -1;
670                         }
671
672                         wsi->opcode = c & 0xf;
673                         wsi->final = !!((c >> 7) & 1);
674
675                         if (wsi->final &&
676                             wsi->opcode == LWS_WS_OPCODE_04__CONTINUATION &&
677                                                    wsi->rx_packet_length == 0) {
678                                 fprintf(stderr,
679                                       "Frame starts with final continuation\n");
680                                 /* kill the connection */
681                                 return -1;
682                         }
683
684                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
685                         break;
686                 }
687                 break;
688
689
690         case LWS_RXPS_04_FRAME_HDR_LEN:
691
692                 if (c & 0x80) {
693                         fprintf(stderr,
694                                       "Frame has extensions set illegally 4\n");
695                         /* kill the connection */
696                         return -1;
697                 }
698
699                 switch (c) {
700                 case 126:
701                         /* control frames are not allowed to have big lengths */
702                         switch (wsi->opcode) {
703                         case LWS_WS_OPCODE_04__CLOSE:
704                         case LWS_WS_OPCODE_04__PING:
705                         case LWS_WS_OPCODE_04__PONG:
706                                 fprintf(stderr, "Control frame asking for "
707                                                 "extended length is illegal\n");
708                                 /* kill the connection */
709                                 return -1;
710                         default:
711                                 break;
712                         }
713                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
714                         break;
715                 case 127:
716                         /* control frames are not allowed to have big lengths */
717                         switch (wsi->opcode) {
718                         case LWS_WS_OPCODE_04__CLOSE:
719                         case LWS_WS_OPCODE_04__PING:
720                         case LWS_WS_OPCODE_04__PONG:
721                                 fprintf(stderr, "Control frame asking for "
722                                                 "extended length is illegal\n");
723                                 /* kill the connection */
724                                 return -1;
725                         default:
726                                 break;
727                         }
728                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
729                         break;
730                 default:
731                         wsi->rx_packet_length = c;
732                         wsi->lws_rx_parse_state =
733                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
734                         break;
735                 }
736                 break;
737
738         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
739                 wsi->rx_packet_length = c << 8;
740                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
741                 break;
742
743         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
744                 wsi->rx_packet_length |= c;
745                 wsi->lws_rx_parse_state =
746                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
747                 break;
748
749         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
750                 if (c & 0x80) {
751                         fprintf(stderr, "b63 of length must be zero\n");
752                         /* kill the connection */
753                         return -1;
754                 }
755 #if defined __LP64__
756                 wsi->rx_packet_length = ((size_t)c) << 56;
757 #else
758                 wsi->rx_packet_length =0;
759 #endif
760                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
761                 break;
762
763         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
764 #if defined __LP64__
765                 wsi->rx_packet_length |= ((size_t)c) << 48;
766 #endif
767                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
768                 break;
769
770         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
771 #if defined __LP64__
772                 wsi->rx_packet_length |= ((size_t)c) << 40;
773 #endif
774                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
775                 break;
776
777         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
778 #if defined __LP64__
779                 wsi->rx_packet_length |= ((size_t)c) << 32;
780 #endif
781                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
782                 break;
783
784         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
785                 wsi->rx_packet_length |= ((size_t)c) << 24;
786                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
787                 break;
788
789         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
790                 wsi->rx_packet_length |= ((size_t)c) << 16;
791                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
792                 break;
793
794         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
795                 wsi->rx_packet_length |= ((size_t)c) << 8;
796                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
797                 break;
798
799         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
800                 wsi->rx_packet_length |= (size_t)c;
801                 wsi->lws_rx_parse_state =
802                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
803                 break;
804
805         case LWS_RXPS_EAT_UNTIL_76_FF:
806                 if (c == 0xff) {
807                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
808                         goto issue;
809                 }
810                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
811                                               (wsi->rx_user_buffer_head++)] = c;
812
813                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
814                         break;
815 issue:
816                 if (wsi->protocol->callback)
817                         wsi->protocol->callback(wsi,
818                                                 LWS_CALLBACK_CLIENT_RECEIVE,
819                                                 wsi->user_space,
820                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
821                                                       wsi->rx_user_buffer_head);
822                 wsi->rx_user_buffer_head = 0;
823                 break;
824         case LWS_RXPS_SEEN_76_FF:
825                 if (c)
826                         break;
827
828                 debug("Seen that client is requesting "
829                                 "a v76 close, sending ack\n");
830                 buf[0] = 0xff;
831                 buf[1] = 0;
832                 n = libwebsocket_write(wsi, buf, 2, LWS_WRITE_HTTP);
833                 if (n < 0) {
834                         fprintf(stderr, "ERROR writing to socket");
835                         return -1;
836                 }
837                 debug("  v76 close ack sent, server closing skt\n");
838                 /* returning < 0 will get it closed in parent */
839                 return -1;
840
841         case LWS_RXPS_PULLING_76_LENGTH:
842                 break;
843
844         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
845                 wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
846                                  (wsi->rx_user_buffer_head++)] = c;
847                 if (--wsi->rx_packet_length == 0) {
848                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
849                         goto spill;
850                 }
851                 if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
852                         break;
853 spill:
854                 /*
855                  * is this frame a control packet we should take care of at this
856                  * layer?  If so service it and hide it from the user callback
857                  */
858
859                 switch (wsi->opcode) {
860                 case LWS_WS_OPCODE_04__CLOSE:
861                         /* parrot the close packet payload back */
862                         n = libwebsocket_write(wsi, (unsigned char *)
863                            &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
864                                      wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
865                         /* close the connection */
866                         return -1;
867
868                 case LWS_WS_OPCODE_04__PING:
869                         /* parrot the ping packet payload back as a pong*/
870                         n = libwebsocket_write(wsi, (unsigned char *)
871                             &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
872                                     wsi->rx_user_buffer_head, LWS_WRITE_PONG);
873                         break;
874
875                 case LWS_WS_OPCODE_04__PONG:
876                         /* keep the statistics... */
877                         wsi->pings_vs_pongs--;
878                         /* ... then just drop it */
879                         wsi->rx_user_buffer_head = 0;
880                         return 0;
881
882                 default:
883                         break;
884                 }
885
886                 /*
887                  * No it's real payload, pass it up to the user callback.
888                  * It's nicely buffered with the pre-padding taken care of
889                  * so it can be sent straight out again using libwebsocket_write
890                  */
891
892                 if (wsi->protocol->callback)
893                         wsi->protocol->callback(wsi,
894                                                 LWS_CALLBACK_CLIENT_RECEIVE,
895                                                 wsi->user_space,
896                           &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
897                                                       wsi->rx_user_buffer_head);
898                 wsi->rx_user_buffer_head = 0;
899                 break;
900         default:
901                 fprintf(stderr, "client rx illegal state\n");
902                 return 1;
903         }
904
905         return 0;
906 }
907
908
909
910 int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
911                                                  unsigned char *buf, size_t len)
912 {
913         int n;
914
915 #ifdef DEBUG
916         fprintf(stderr, "received %d byte packet\n", (int)len);
917         for (n = 0; n < len; n++)
918                 fprintf(stderr, "%02X ", buf[n]);
919         fprintf(stderr, "\n");
920 #endif
921
922         /* let the rx protocol state machine have as much as it needs */
923
924         n = 0;
925         while (n < len)
926                 if (libwebsocket_rx_sm(wsi, buf[n++]) < 0)
927                         return -1;
928
929         return 0;
930 }
931
932
933 static int
934 libwebsocket_04_frame_mask_generate(struct libwebsocket *wsi)
935 {
936         int fd;
937         char buf[4 + 20];
938         int n;
939
940         /* fetch the per-frame nonce */
941
942         fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
943         if (fd < 1) {
944                 fprintf(stderr, "Unable to open random device %s\n",
945                                                         SYSTEM_RANDOM_FILEPATH);
946                 return 1;
947         }
948         n = read(fd, wsi->frame_masking_nonce_04, 4);
949         if (n != 4) {
950                 fprintf(stderr, "Unable to read from random device %s %d\n",
951                                                      SYSTEM_RANDOM_FILEPATH, n);
952                 return 1;
953         }
954         close(fd);
955
956         /*
957          * the frame key is the frame nonce (4 bytes) followed by the
958          * connection masking key, hashed by SHA1
959          */
960
961         memcpy(buf, wsi->frame_masking_nonce_04, 4);
962         memcpy(buf + 4, wsi->masking_key_04, 20);
963
964         /* concatenate the nonce with the connection key then hash it */
965
966         SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
967
968         /* start masking from first byte of masking key buffer */
969         wsi->frame_mask_index = 0;
970
971         return 0;
972 }
973
974
975 /**
976  * libwebsocket_write() - Apply protocol then write data to client
977  * @wsi:        Websocket instance (available from user callback)
978  * @buf:        The data to send.  For data being sent on a websocket
979  *              connection (ie, not default http), this buffer MUST have
980  *              LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
981  *              and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
982  *              in the buffer after (buf + len).  This is so the protocol
983  *              header and trailer data can be added in-situ.
984  * @len:        Count of the data bytes in the payload starting from buf
985  * @protocol:   Use LWS_WRITE_HTTP to reply to an http connection, and one
986  *              of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
987  *              data on a websockets connection.  Remember to allow the extra
988  *              bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
989  *              are used.
990  *
991  *      This function provides the way to issue data back to the client
992  *      for both http and websocket protocols.
993  *
994  *      In the case of sending using websocket protocol, be sure to allocate
995  *      valid storage before and after buf as explained above.  This scheme
996  *      allows maximum efficiency of sending data and protocol in a single
997  *      packet while not burdening the user code with any protocol knowledge.
998  */
999
1000 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
1001                           size_t len, enum libwebsocket_write_protocol protocol)
1002 {
1003         int n;
1004         int pre = 0;
1005         int post = 0;
1006         unsigned int shift = 7;
1007
1008         if (len == 0) {
1009                 fprintf(stderr, "zero length libwebsocket_write attempt\n");
1010                 return 0;
1011         }
1012
1013         if (protocol == LWS_WRITE_HTTP)
1014                 goto send_raw;
1015
1016         /* websocket protocol, either binary or text */
1017
1018         if (wsi->state != WSI_STATE_ESTABLISHED)
1019                 return -1;
1020
1021         switch (wsi->ietf_spec_revision) {
1022         /* chrome likes this as of 30 Oct */
1023         /* Firefox 4.0b6 likes this as of 30 Oct */
1024         case 0:
1025                 if ((protocol & 0xf) == LWS_WRITE_BINARY) {
1026                         /* in binary mode we send 7-bit used length blocks */
1027                         pre = 1;
1028                         while (len & (127 << shift)) {
1029                                 pre++;
1030                                 shift += 7;
1031                         }
1032                         n = 0;
1033                         shift -= 7;
1034                         while (shift >= 0) {
1035                                 if (shift)
1036                                         buf[0 - pre + n] =
1037                                                   ((len >> shift) & 127) | 0x80;
1038                                 else
1039                                         buf[0 - pre + n] =
1040                                                   ((len >> shift) & 127);
1041                                 n++;
1042                                 shift -= 7;
1043                         }
1044                         break;
1045                 }
1046
1047                 /* frame type = text, length-free spam mode */
1048
1049                 buf[-1] = 0;
1050                 buf[len] = 0xff; /* EOT marker */
1051                 pre = 1;
1052                 post = 1;
1053                 break;
1054
1055         case 4:
1056
1057                 switch (protocol & 0xf) {
1058                 case LWS_WRITE_TEXT:
1059                         n = LWS_WS_OPCODE_04__TEXT_FRAME;
1060                         break;
1061                 case LWS_WRITE_BINARY:
1062                         n = LWS_WS_OPCODE_04__BINARY_FRAME;
1063                         break;
1064                 case LWS_WRITE_CLOSE:
1065                         n = LWS_WS_OPCODE_04__CLOSE;
1066                         break;
1067                 case LWS_WRITE_PING:
1068                         n = LWS_WS_OPCODE_04__PING;
1069                         wsi->pings_vs_pongs++;
1070                         break;
1071                 case LWS_WRITE_PONG:
1072                         n = LWS_WS_OPCODE_04__PONG;
1073                         break;
1074                 default:
1075                         fprintf(stderr, "libwebsocket_write: unknown write "
1076                                                          "opcode / protocol\n");
1077                         return -1;
1078                 }
1079
1080                 if (!(protocol & LWS_WRITE_NO_FIN))
1081                         n |= 1 << 7;
1082
1083                 if (len < 126) {
1084                         buf[-2] = n;
1085                         buf[-1] = len;
1086                         pre = 2;
1087                 } else {
1088                         if (len < 65536) {
1089                                 buf[-4] = n;
1090                                 buf[-3] = 126;
1091                                 buf[-2] = len >> 8;
1092                                 buf[-1] = len;
1093                                 pre = 4;
1094                         } else {
1095                                 buf[-10] = n;
1096                                 buf[-9] = 127;
1097 #if defined __LP64__
1098                                         buf[-8] = (len >> 56) & 0x7f;
1099                                         buf[-7] = len >> 48;
1100                                         buf[-6] = len >> 40;
1101                                         buf[-5] = len >> 32;
1102 #else
1103                                         buf[-8] = 0;
1104                                         buf[-7] = 0;
1105                                         buf[-6] = 0;
1106                                         buf[-5] = 0;
1107 #endif
1108                                 buf[-4] = len >> 24;
1109                                 buf[-3] = len >> 16;
1110                                 buf[-2] = len >> 8;
1111                                 buf[-1] = len;
1112                                 pre = 10;
1113                         }
1114                 }
1115                 break;
1116         }
1117
1118 #if 0
1119         for (n = 0; n < (len + pre + post); n++)
1120                 fprintf(stderr, "%02X ", buf[n - pre]);
1121
1122         fprintf(stderr, "\n");
1123 #endif
1124
1125         /*
1126          * Deal with masking if appropriate
1127          */
1128
1129         if (wsi->client_mode && wsi->ietf_spec_revision == 4) {
1130
1131                 if (libwebsocket_04_frame_mask_generate(wsi)) {
1132                         fprintf(stderr, "libwebsocket_write: "
1133                                               "frame mask generation failed\n");
1134                         return 1;
1135                 }
1136
1137                 /*
1138                  * use the XOR masking against everything we send
1139                  * past the frame nonce
1140                  */
1141
1142                 for (n = 0; n < (len + pre + post); n++)
1143                         buf[n - pre] = xor_mask(wsi, buf[n - pre]);
1144
1145                 /* make space for the frame nonce in clear */
1146                 pre += 4;
1147
1148                 /* copy the frame nonce into place */
1149                 memcpy(&buf[0 - pre], wsi->frame_masking_nonce_04, 4);
1150         }
1151
1152 send_raw:
1153 #ifdef LWS_OPENSSL_SUPPORT
1154         if (wsi->ssl) {
1155                 n = SSL_write(wsi->ssl, buf - pre, len + pre + post);
1156                 if (n < 0) {
1157                         fprintf(stderr, "ERROR writing to socket\n");
1158                         return -1;
1159                 }
1160         } else {
1161 #endif
1162                 n = send(wsi->sock, buf - pre, len + pre + post, MSG_NOSIGNAL);
1163                 if (n < 0) {
1164                         fprintf(stderr, "ERROR writing to socket\n");
1165                         return -1;
1166                 }
1167 #ifdef LWS_OPENSSL_SUPPORT
1168         }
1169 #endif
1170
1171         debug("written %d bytes to client\n", (int)len);
1172
1173         return 0;
1174 }
1175
1176
1177 /**
1178  * libwebsockets_serve_http_file() - Send a file back to the client using http
1179  * @wsi:                Websocket instance (available from user callback)
1180  * @file:               The file to issue over http
1181  * @content_type:       The http content type, eg, text/html
1182  *
1183  *      This function is intended to be called from the callback in response
1184  *      to http requests from the client.  It allows the callback to issue
1185  *      local files down the http link in a single step.
1186  */
1187
1188 int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file,
1189                                                        const char *content_type)
1190 {
1191         int fd;
1192         struct stat stat;
1193         char buf[512];
1194         char *p = buf;
1195         int n;
1196
1197         fd = open(file, O_RDONLY);
1198         if (fd < 1) {
1199                 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
1200                         "Server: libwebsockets\x0d\x0a"
1201                         "\x0d\x0a"
1202                 );
1203                 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
1204                                                                 LWS_WRITE_HTTP);
1205
1206                 return -1;
1207         }
1208
1209         fstat(fd, &stat);
1210         p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
1211                         "Server: libwebsockets\x0d\x0a"
1212                         "Content-Type: %s\x0d\x0a"
1213                         "Content-Length: %u\x0d\x0a"
1214                         "\x0d\x0a", content_type, (unsigned int)stat.st_size);
1215
1216         libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
1217
1218         n = 1;
1219         while (n > 0) {
1220                 n = read(fd, buf, 512);
1221                 if (n <= 0)
1222                         continue;
1223                 libwebsocket_write(wsi, (unsigned char *)buf, n,
1224                                                                 LWS_WRITE_HTTP);
1225         }
1226
1227         close(fd);
1228
1229         return 0;
1230 }
1231
1232
1233 /**
1234  * libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
1235  *                                            rx packet is complete
1236  * @wsi:                Websocket instance (available from user callback)
1237  *
1238  *      This function is intended to be called from the callback if the
1239  *  user code is interested in "complete packets" from the client.
1240  *  libwebsockets just passes through payload as it comes and issues a buffer
1241  *  additionally when it hits a built-in limit.  The LWS_CALLBACK_RECEIVE
1242  *  callback handler can use this API to find out if the buffer it has just
1243  *  been given is the last piece of a "complete packet" from the client --
1244  *  when that is the case libwebsockets_remaining_packet_payload() will return
1245  *  0.
1246  *
1247  *  Many protocols won't care becuse their packets are always small.
1248  */
1249
1250 size_t
1251 libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
1252 {
1253         return wsi->rx_packet_length;
1254 }