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