close add callback to get peer close reason
[platform/upstream/libwebsockets.git] / lib / parsers.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2013 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 unsigned char lextable[] = {
25         #include "lextable.h"
26 };
27
28 #define FAIL_CHAR 0x08
29
30 int lextable_decode(int pos, char c)
31 {
32         c = tolower(c);
33
34         while (1) {
35                 if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */
36                         if ((lextable[pos] & 0x7f) != c)
37                                 return -1;
38                         /* fall thru */
39                         pos++;
40                         if (lextable[pos] == FAIL_CHAR)
41                                 return -1;
42                         return pos;
43                 }
44
45                 if (lextable[pos] == FAIL_CHAR)
46                         return -1;
47
48                 /* b7 = 0, end or 3-byte */
49                 if (lextable[pos] < FAIL_CHAR) /* terminal marker */
50                         return pos;
51
52                 if (lextable[pos] == c) /* goto */
53                         return pos + (lextable[pos + 1]) +
54                                                 (lextable[pos + 2] << 8);
55                 /* fall thru goto */
56                 pos += 3;
57                 /* continue */
58         }
59 }
60
61 int lws_allocate_header_table(struct lws *wsi)
62 {
63         struct lws_context *context = wsi->context;
64         int n;
65
66         lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi,
67                  (void *)wsi->u.hdr.ah);
68
69         /* if we are already bound to one, just clear it down */
70         if (wsi->u.hdr.ah)
71                 goto reset;
72         /*
73          * server should have suppressed the accept of a new wsi before this
74          * became the case.  If initiating multiple client connects, make sure
75          * the ah pool is big enough to cope, or be prepared to retry
76          */
77         if (context->ah_count_in_use == context->max_http_header_pool) {
78                 lwsl_err("No free ah\n");
79                 return -1;
80         }
81
82         for (n = 0; n < context->max_http_header_pool; n++)
83                 if (!context->ah_pool[n].in_use)
84                         break;
85
86         /* if the count of in use said something free... */
87         assert(n != context->max_http_header_pool);
88
89         wsi->u.hdr.ah = &context->ah_pool[n];
90         wsi->u.hdr.ah->in_use = 1;
91
92         context->ah_count_in_use++;
93         /* if we used up all the ah, defeat accepting new server connections */
94         if (context->ah_count_in_use == context->max_http_header_pool)
95                 if (_lws_server_listen_accept_flow_control(context, 0))
96                         return 1;
97
98         lwsl_debug("%s: wsi %p: ah %p: count %d (on exit)\n",
99                  __func__, (void *)wsi, (void *)wsi->u.hdr.ah,
100                  context->ah_count_in_use);
101
102 reset:
103         /* init the ah to reflect no headers or data have appeared yet */
104         memset(wsi->u.hdr.ah->frag_index, 0, sizeof(wsi->u.hdr.ah->frag_index));
105         wsi->u.hdr.ah->nfrag = 0;
106         wsi->u.hdr.ah->pos = 0;
107
108         return 0;
109 }
110
111 int lws_free_header_table(struct lws *wsi)
112 {
113         struct lws_context *context = wsi->context;
114
115         lwsl_debug("%s: wsi %p: ah %p (count = %d)\n", __func__, (void *)wsi,
116                  (void *)wsi->u.hdr.ah, context->ah_count_in_use);
117
118         assert(wsi->u.hdr.ah);
119         if (!wsi->u.hdr.ah)
120                 return 0;
121
122         /* if we think we're freeing one, there should be one to free */
123         assert(context->ah_count_in_use > 0);
124
125         assert(wsi->u.hdr.ah->in_use);
126         wsi->u.hdr.ah->in_use = 0;
127
128         /* if we just freed up one ah, allow new server connection */
129         if (context->ah_count_in_use == context->max_http_header_pool)
130                 if (_lws_server_listen_accept_flow_control(context, 1))
131                         return 1;
132
133         context->ah_count_in_use--;
134         wsi->u.hdr.ah = NULL;
135
136         return 0;
137 }
138
139 LWS_VISIBLE int
140 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx)
141 {
142         int n;
143
144         n = wsi->u.hdr.ah->frag_index[h];
145         if (!n)
146                 return 0;
147         do {
148                 if (!frag_idx)
149                         return wsi->u.hdr.ah->frags[n].len;
150                 n = wsi->u.hdr.ah->frags[n].nfrag;
151         } while (frag_idx-- && n);
152
153         return 0;
154 }
155
156 LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h)
157 {
158         int n;
159         int len = 0;
160
161         n = wsi->u.hdr.ah->frag_index[h];
162         if (!n)
163                 return 0;
164         do {
165                 len += wsi->u.hdr.ah->frags[n].len;
166                 n = wsi->u.hdr.ah->frags[n].nfrag;
167         } while (n);
168
169         return len;
170 }
171
172 LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
173                                       enum lws_token_indexes h, int frag_idx)
174 {
175         int n = 0;
176         int f = wsi->u.hdr.ah->frag_index[h];
177
178         while (n < frag_idx) {
179                 f = wsi->u.hdr.ah->frags[f].nfrag;
180                 if (!f)
181                         return -1;
182                 n++;
183         }
184
185         if (wsi->u.hdr.ah->frags[f].len >= len)
186                 return -1;
187
188         memcpy(dst, wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[f].offset,
189                wsi->u.hdr.ah->frags[f].len);
190         dst[wsi->u.hdr.ah->frags[f].len] = '\0';
191
192         return wsi->u.hdr.ah->frags[f].len;
193 }
194
195 LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
196                              enum lws_token_indexes h)
197 {
198         int toklen = lws_hdr_total_length(wsi, h);
199         int n;
200
201         if (toklen >= len)
202                 return -1;
203
204         n = wsi->u.hdr.ah->frag_index[h];
205         if (!n)
206                 return 0;
207
208         do {
209                 strcpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
210                 dst += wsi->u.hdr.ah->frags[n].len;
211                 n = wsi->u.hdr.ah->frags[n].nfrag;
212         } while (n);
213
214         return toklen;
215 }
216
217 char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
218 {
219         int n;
220
221         n = wsi->u.hdr.ah->frag_index[h];
222         if (!n)
223                 return NULL;
224
225         return wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[n].offset;
226 }
227
228 int lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h,
229                           const char *s)
230 {
231         wsi->u.hdr.ah->nfrag++;
232         if (wsi->u.hdr.ah->nfrag == ARRAY_SIZE(wsi->u.hdr.ah->frags)) {
233                 lwsl_warn("More hdr frags than we can deal with, dropping\n");
234                 return -1;
235         }
236
237         wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->nfrag;
238
239         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].offset = wsi->u.hdr.ah->pos;
240         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len = 0;
241         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].nfrag = 0;
242
243         do {
244                 if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
245                         lwsl_err("Ran out of header data space\n");
246                         return -1;
247                 }
248                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s;
249                 if (*s)
250                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
251         } while (*s++);
252
253         return 0;
254 }
255
256 static signed char char_to_hex(const char c)
257 {
258         if (c >= '0' && c <= '9')
259                 return c - '0';
260
261         if (c >= 'a' && c <= 'f')
262                 return c - 'a' + 10;
263
264         if (c >= 'A' && c <= 'F')
265                 return c - 'A' + 10;
266
267         return -1;
268 }
269
270 static int issue_char(struct lws *wsi, unsigned char c)
271 {
272         unsigned short frag_len;
273
274         if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
275                 lwsl_warn("excessive header content\n");
276                 return -1;
277         }
278
279         frag_len = wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len;
280         /*
281          * If we haven't hit the token limit, just copy the character into
282          * the header
283          */
284         if (frag_len < wsi->u.hdr.current_token_limit) {
285                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
286                 if (c)
287                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
288                 return 0;
289         }
290
291         /* Insert a null character when we *hit* the limit: */
292         if (frag_len == wsi->u.hdr.current_token_limit) {
293                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
294                 lwsl_warn("header %i exceeds limit %d\n",
295                           wsi->u.hdr.parser_state, wsi->u.hdr.current_token_limit);
296         }
297
298         return 1;
299 }
300
301 int lws_parse(struct lws *wsi, unsigned char c)
302 {
303         static const unsigned char methods[] = {
304                 WSI_TOKEN_GET_URI,
305                 WSI_TOKEN_POST_URI,
306                 WSI_TOKEN_OPTIONS_URI,
307                 WSI_TOKEN_PUT_URI,
308                 WSI_TOKEN_PATCH_URI,
309                 WSI_TOKEN_DELETE_URI,
310         };
311         struct allocated_headers *ah = wsi->u.hdr.ah;
312         struct lws_context *context = wsi->context;
313         unsigned int n, m, enc = 0;
314
315         switch (wsi->u.hdr.parser_state) {
316         default:
317
318                 lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
319
320                 /* collect into malloc'd buffers */
321                 /* optional initial space swallow */
322                 if (!ah->frags[ah->frag_index[
323                                       wsi->u.hdr.parser_state]].len && c == ' ')
324                         break;
325
326                 for (m = 0; m < ARRAY_SIZE(methods); m++)
327                         if (wsi->u.hdr.parser_state == methods[m])
328                                 break;
329                 if (m == ARRAY_SIZE(methods))
330                         /* it was not any of the methods */
331                         goto check_eol;
332
333                 /* special URI processing... end at space */
334
335                 if (c == ' ') {
336                         /* enforce starting with / */
337                         if (!ah->frags[ah->nfrag].len)
338                                 if (issue_char(wsi, '/') < 0)
339                                         return -1;
340
341                         /* begin parsing HTTP version: */
342                         if (issue_char(wsi, '\0') < 0)
343                                 return -1;
344                         wsi->u.hdr.parser_state = WSI_TOKEN_HTTP;
345                         goto start_fragment;
346                 }
347
348                 /* special URI processing... convert %xx */
349
350                 switch (wsi->u.hdr.ues) {
351                 case URIES_IDLE:
352                         if (c == '%') {
353                                 wsi->u.hdr.ues = URIES_SEEN_PERCENT;
354                                 goto swallow;
355                         }
356                         break;
357                 case URIES_SEEN_PERCENT:
358                         if (char_to_hex(c) < 0) {
359                                 /* regurgitate */
360                                 if (issue_char(wsi, '%') < 0)
361                                         return -1;
362                                 wsi->u.hdr.ues = URIES_IDLE;
363                                 /* continue on to assess c */
364                                 break;
365                         }
366                         wsi->u.hdr.esc_stash = c;
367                         wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
368                         goto swallow;
369
370                 case URIES_SEEN_PERCENT_H1:
371                         if (char_to_hex(c) < 0) {
372                                 /* regurgitate */
373                                 issue_char(wsi, '%');
374                                 wsi->u.hdr.ues = URIES_IDLE;
375                                 /* regurgitate + assess */
376                                 if (lws_parse(wsi, wsi->u.hdr.esc_stash) < 0)
377                                         return -1;
378                                 /* continue on to assess c */
379                                 break;
380                         }
381                         c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
382                                         char_to_hex(c);
383                         enc = 1;
384                         wsi->u.hdr.ues = URIES_IDLE;
385                         break;
386                 }
387
388                 /*
389                  * special URI processing...
390                  *  convert /.. or /... or /../ etc to /
391                  *  convert /./ to /
392                  *  convert // or /// etc to /
393                  *  leave /.dir or whatever alone
394                  */
395
396                 switch (wsi->u.hdr.ups) {
397                 case URIPS_IDLE:
398                         /* genuine delimiter */
399                         if ((c == '&' || c == ';') && !enc) {
400                                 issue_char(wsi, c);
401                                 /* swallow the terminator */
402                                 ah->frags[ah->nfrag].len--;
403                                 /* link to next fragment */
404                                 ah->frags[ah->nfrag].nfrag = ah->nfrag + 1;
405                                 ah->nfrag++;
406                                 if (ah->nfrag >= ARRAY_SIZE(ah->frags))
407                                         goto excessive;
408                                 /* start next fragment after the & */
409                                 wsi->u.hdr.post_literal_equal = 0;
410                                 ah->frags[ah->nfrag].offset = ah->pos;
411                                 ah->frags[ah->nfrag].len = 0;
412                                 ah->frags[ah->nfrag].nfrag = 0;
413                                 goto swallow;
414                         }
415                         /* uriencoded = in the name part, disallow */
416                         if (c == '=' && enc && !wsi->u.hdr.post_literal_equal)
417                                 c = '_';
418
419                         /* after the real =, we don't care how many = */
420                         if (c == '=' && !enc)
421                                 wsi->u.hdr.post_literal_equal = 1;
422
423                         /* + to space */
424                         if (c == '+' && !enc)
425                                 c = ' ';
426                         /* issue the first / always */
427                         if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS])
428                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
429                         break;
430                 case URIPS_SEEN_SLASH:
431                         /* swallow subsequent slashes */
432                         if (c == '/')
433                                 goto swallow;
434                         /* track and swallow the first . after / */
435                         if (c == '.') {
436                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT;
437                                 goto swallow;
438                         }
439                         wsi->u.hdr.ups = URIPS_IDLE;
440                         break;
441                 case URIPS_SEEN_SLASH_DOT:
442                         /* swallow second . */
443                         if (c == '.') {
444                                 /*
445                                  * back up one dir level if possible
446                                  * safe against header fragmentation because
447                                  * the method URI can only be in 1 fragment
448                                  */
449                                 if (ah->frags[ah->nfrag].len > 2) {
450                                         ah->pos--;
451                                         ah->frags[ah->nfrag].len--;
452                                         do {
453                                                 ah->pos--;
454                                                 ah->frags[ah->nfrag].len--;
455                                         } while (ah->frags[ah->nfrag].len > 1 &&
456                                                  ah->data[ah->pos] != '/');
457                                 }
458                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
459                                 goto swallow;
460                         }
461                         /* change /./ to / */
462                         if (c == '/') {
463                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
464                                 goto swallow;
465                         }
466                         /* it was like /.dir ... regurgitate the . */
467                         wsi->u.hdr.ups = URIPS_IDLE;
468                         if (issue_char(wsi, '.') < 0)
469                                 return -1;
470                         break;
471
472                 case URIPS_SEEN_SLASH_DOT_DOT:
473                         /* swallow prior .. chars and any subsequent . */
474                         if (c == '.')
475                                 goto swallow;
476                         /* last issued was /, so another / == // */
477                         if (c == '/')
478                                 goto swallow;
479                         /* last we issued was / so SEEN_SLASH */
480                         wsi->u.hdr.ups = URIPS_SEEN_SLASH;
481                         break;
482                 }
483
484                 if (c == '?' && !enc &&
485                     !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */
486                         /* seal off uri header */
487                         ah->data[ah->pos++] = '\0';
488
489                         /* move to using WSI_TOKEN_HTTP_URI_ARGS */
490                         ah->nfrag++;
491                         if (ah->nfrag >= ARRAY_SIZE(ah->frags))
492                                 goto excessive;
493                         ah->frags[ah->nfrag].offset = ah->pos;
494                         ah->frags[ah->nfrag].len = 0;
495                         ah->frags[ah->nfrag].nfrag = 0;
496
497                         wsi->u.hdr.post_literal_equal = 0;
498                         ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag;
499                         wsi->u.hdr.ups = URIPS_IDLE;
500                         goto swallow;
501                 }
502
503 check_eol:
504
505                 /* bail at EOL */
506                 if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE &&
507                                                                   c == '\x0d') {
508                         c = '\0';
509                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
510                         lwsl_parser("*\n");
511                 }
512
513                 n = issue_char(wsi, c);
514                 if ((int)n < 0)
515                         return -1;
516                 if (n > 0)
517                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
518
519 swallow:
520                 /* per-protocol end of headers management */
521
522                 if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
523                         goto set_parsing_complete;
524                 break;
525
526                 /* collecting and checking a name part */
527         case WSI_TOKEN_NAME_PART:
528                 lwsl_parser("WSI_TOKEN_NAME_PART '%c' (mode=%d)\n", c, wsi->mode);
529
530                 wsi->u.hdr.lextable_pos =
531                                 lextable_decode(wsi->u.hdr.lextable_pos, c);
532                 /*
533                  * Server needs to look out for unknown methods...
534                  */
535                 if (wsi->u.hdr.lextable_pos < 0 &&
536                     wsi->mode == LWSCM_HTTP_SERVING) {
537                         /* this is not a header we know about */
538                         for (m = 0; m < ARRAY_SIZE(methods); m++)
539                                 if (ah->frag_index[methods[m]]) {
540                                         /*
541                                          * already had the method, no idea what
542                                          * this crap from the client is, ignore
543                                          */
544                                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
545                                         break;
546                                 }
547                         /*
548                          * hm it's an unknown http method from a client in fact,
549                          * treat as dangerous
550                          */
551                         if (m == ARRAY_SIZE(methods)) {
552                                 lwsl_info("Unknown method - dropping\n");
553                                 return -1;
554                         }
555                         break;
556                 }
557                 /*
558                  * ...otherwise for a client, let him ignore unknown headers
559                  * coming from the server
560                  */
561                 if (wsi->u.hdr.lextable_pos < 0) {
562                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
563                         break;
564                 }
565
566                 if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
567                         /* terminal state */
568
569                         n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
570                                         lextable[wsi->u.hdr.lextable_pos + 1];
571
572                         lwsl_parser("known hdr %d\n", n);
573                         for (m = 0; m < ARRAY_SIZE(methods); m++)
574                                 if (n == methods[m] &&
575                                                 ah->frag_index[
576                                                         methods[m]]) {
577                                         lwsl_warn("Duplicated method\n");
578                                         return -1;
579                                 }
580
581                         /*
582                          * WSORIGIN is protocol equiv to ORIGIN,
583                          * JWebSocket likes to send it, map to ORIGIN
584                          */
585                         if (n == WSI_TOKEN_SWORIGIN)
586                                 n = WSI_TOKEN_ORIGIN;
587
588                         wsi->u.hdr.parser_state = (enum lws_token_indexes)
589                                                         (WSI_TOKEN_GET_URI + n);
590
591                         if (context->token_limits)
592                                 wsi->u.hdr.current_token_limit =
593                                         context->token_limits->token_limit[
594                                                        wsi->u.hdr.parser_state];
595                         else
596                                 wsi->u.hdr.current_token_limit =
597                                         wsi->context->max_http_header_data;
598
599                         if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
600                                 goto set_parsing_complete;
601
602                         goto start_fragment;
603                 }
604                 break;
605
606 start_fragment:
607                 ah->nfrag++;
608 excessive:
609                 if (ah->nfrag == ARRAY_SIZE(ah->frags)) {
610                         lwsl_warn("More hdr frags than we can deal with\n");
611                         return -1;
612                 }
613
614                 ah->frags[ah->nfrag].offset = ah->pos;
615                 ah->frags[ah->nfrag].len = 0;
616                 ah->frags[ ah->nfrag].nfrag = 0;
617
618                 n = ah->frag_index[wsi->u.hdr.parser_state];
619                 if (!n) { /* first fragment */
620                         ah->frag_index[wsi->u.hdr.parser_state] = ah->nfrag;
621                         break;
622                 }
623                 /* continuation */
624                 while (ah->frags[n].nfrag)
625                                 n = ah->frags[n].nfrag;
626                 ah->frags[n].nfrag = ah->nfrag;
627
628                 if (ah->pos == wsi->context->max_http_header_data) {
629                         lwsl_warn("excessive header content\n");
630                         return -1;
631                 }
632
633                 ah->data[ah->pos++] = ' ';
634                 ah->frags[ah->nfrag].len++;
635                 break;
636
637                 /* skipping arg part of a name we didn't recognize */
638         case WSI_TOKEN_SKIPPING:
639                 lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
640
641                 if (c == '\x0d')
642                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
643                 break;
644
645         case WSI_TOKEN_SKIPPING_SAW_CR:
646                 lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
647                 if (c == '\x0a') {
648                         wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
649                         wsi->u.hdr.lextable_pos = 0;
650                 } else
651                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
652                 break;
653                 /* we're done, ignore anything else */
654
655         case WSI_PARSING_COMPLETE:
656                 lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c);
657                 break;
658         }
659
660         return 0;
661
662 set_parsing_complete:
663
664         if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
665                 if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
666                         wsi->ietf_spec_revision =
667                                atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
668
669                 lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision);
670         }
671         wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
672         wsi->hdr_parsing_completed = 1;
673
674         return 0;
675 }
676
677
678 /**
679  * lws_frame_is_binary: true if the current frame was sent in binary mode
680  *
681  * @wsi: the connection we are inquiring about
682  *
683  * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if
684  * it's interested to see if the frame it's dealing with was sent in binary
685  * mode.
686  */
687
688 LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi)
689 {
690         return wsi->u.ws.frame_is_binary;
691 }
692
693 int
694 lws_rx_sm(struct lws *wsi, unsigned char c)
695 {
696         struct lws_tokens eff_buf;
697         int ret = 0;
698         int callback_action = LWS_CALLBACK_RECEIVE;
699
700         switch (wsi->lws_rx_parse_state) {
701         case LWS_RXPS_NEW:
702
703                 switch (wsi->ietf_spec_revision) {
704                 case 13:
705                         /*
706                          * no prepended frame key any more
707                          */
708                         wsi->u.ws.all_zero_nonce = 1;
709                         goto handle_first;
710
711                 default:
712                         lwsl_warn("lws_rx_sm: unknown spec version %d\n",
713                                                        wsi->ietf_spec_revision);
714                         break;
715                 }
716                 break;
717         case LWS_RXPS_04_MASK_NONCE_1:
718                 wsi->u.ws.mask_nonce[1] = c;
719                 if (c)
720                         wsi->u.ws.all_zero_nonce = 0;
721                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
722                 break;
723         case LWS_RXPS_04_MASK_NONCE_2:
724                 wsi->u.ws.mask_nonce[2] = c;
725                 if (c)
726                         wsi->u.ws.all_zero_nonce = 0;
727                 wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
728                 break;
729         case LWS_RXPS_04_MASK_NONCE_3:
730                 wsi->u.ws.mask_nonce[3] = c;
731                 if (c)
732                         wsi->u.ws.all_zero_nonce = 0;
733
734                 /*
735                  * start from the zero'th byte in the XOR key buffer since
736                  * this is the start of a frame with a new key
737                  */
738
739                 wsi->u.ws.frame_mask_index = 0;
740
741                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
742                 break;
743
744         /*
745          *  04 logical framing from the spec (all this is masked when incoming
746          *  and has to be unmasked)
747          *
748          * We ignore the possibility of extension data because we don't
749          * negotiate any extensions at the moment.
750          *
751          *    0                   1                   2                   3
752          *    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
753          *   +-+-+-+-+-------+-+-------------+-------------------------------+
754          *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
755          *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
756          *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
757          *   | |1|2|3|       |4|             |                               |
758          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
759          *   |     Extended payload length continued, if payload len == 127  |
760          *   + - - - - - - - - - - - - - - - +-------------------------------+
761          *   |                               |         Extension data        |
762          *   +-------------------------------+ - - - - - - - - - - - - - - - +
763          *   :                                                               :
764          *   +---------------------------------------------------------------+
765          *   :                       Application data                        :
766          *   +---------------------------------------------------------------+
767          *
768          *  We pass payload through to userland as soon as we get it, ignoring
769          *  FIN.  It's up to userland to buffer it up if it wants to see a
770          *  whole unfragmented block of the original size (which may be up to
771          *  2^63 long!)
772          */
773
774         case LWS_RXPS_04_FRAME_HDR_1:
775 handle_first:
776
777                 wsi->u.ws.opcode = c & 0xf;
778                 wsi->u.ws.rsv = c & 0x70;
779                 wsi->u.ws.final = !!((c >> 7) & 1);
780
781                 switch (wsi->u.ws.opcode) {
782                 case LWSWSOPC_TEXT_FRAME:
783                 case LWSWSOPC_BINARY_FRAME:
784                         wsi->u.ws.frame_is_binary =
785                              wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME;
786                         break;
787                 }
788                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
789                 break;
790
791         case LWS_RXPS_04_FRAME_HDR_LEN:
792
793                 wsi->u.ws.this_frame_masked = !!(c & 0x80);
794
795                 switch (c & 0x7f) {
796                 case 126:
797                         /* control frames are not allowed to have big lengths */
798                         if (wsi->u.ws.opcode & 8)
799                                 goto illegal_ctl_length;
800
801                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
802                         break;
803                 case 127:
804                         /* control frames are not allowed to have big lengths */
805                         if (wsi->u.ws.opcode & 8)
806                                 goto illegal_ctl_length;
807
808                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
809                         break;
810                 default:
811                         wsi->u.ws.rx_packet_length = c & 0x7f;
812                         if (wsi->u.ws.this_frame_masked)
813                                 wsi->lws_rx_parse_state =
814                                                 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
815                         else
816                                 if (wsi->u.ws.rx_packet_length)
817                                         wsi->lws_rx_parse_state =
818                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
819                                 else {
820                                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
821                                         goto spill;
822                                 }
823                         break;
824                 }
825                 break;
826
827         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
828                 wsi->u.ws.rx_packet_length = c << 8;
829                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
830                 break;
831
832         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
833                 wsi->u.ws.rx_packet_length |= c;
834                 if (wsi->u.ws.this_frame_masked)
835                         wsi->lws_rx_parse_state =
836                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
837                 else
838                         wsi->lws_rx_parse_state =
839                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
840                 break;
841
842         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
843                 if (c & 0x80) {
844                         lwsl_warn("b63 of length must be zero\n");
845                         /* kill the connection */
846                         return -1;
847                 }
848 #if defined __LP64__
849                 wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
850 #else
851                 wsi->u.ws.rx_packet_length = 0;
852 #endif
853                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
854                 break;
855
856         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
857 #if defined __LP64__
858                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
859 #endif
860                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
861                 break;
862
863         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
864 #if defined __LP64__
865                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
866 #endif
867                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
868                 break;
869
870         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
871 #if defined __LP64__
872                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
873 #endif
874                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
875                 break;
876
877         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
878                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
879                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
880                 break;
881
882         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
883                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
884                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
885                 break;
886
887         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
888                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
889                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
890                 break;
891
892         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
893                 wsi->u.ws.rx_packet_length |= ((size_t)c);
894                 if (wsi->u.ws.this_frame_masked)
895                         wsi->lws_rx_parse_state =
896                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
897                 else
898                         wsi->lws_rx_parse_state =
899                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
900                 break;
901
902         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
903                 wsi->u.ws.mask_nonce[0] = c;
904                 if (c)
905                         wsi->u.ws.all_zero_nonce = 0;
906                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
907                 break;
908
909         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
910                 wsi->u.ws.mask_nonce[1] = c;
911                 if (c)
912                         wsi->u.ws.all_zero_nonce = 0;
913                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
914                 break;
915
916         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
917                 wsi->u.ws.mask_nonce[2] = c;
918                 if (c)
919                         wsi->u.ws.all_zero_nonce = 0;
920                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
921                 break;
922
923         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
924                 wsi->u.ws.mask_nonce[3] = c;
925                 if (c)
926                         wsi->u.ws.all_zero_nonce = 0;
927                 wsi->lws_rx_parse_state =
928                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
929                 wsi->u.ws.frame_mask_index = 0;
930                 if (wsi->u.ws.rx_packet_length == 0) {
931                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
932                         goto spill;
933                 }
934                 break;
935
936
937         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
938
939                 if (!wsi->u.ws.rx_user_buffer) {
940                         lwsl_err("NULL user buffer...\n");
941                         return 1;
942                 }
943
944                 if (wsi->u.ws.all_zero_nonce)
945                         wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
946                                (wsi->u.ws.rx_user_buffer_head++)] = c;
947                 else
948                         wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
949                                (wsi->u.ws.rx_user_buffer_head++)] =
950                                    c ^ wsi->u.ws.mask_nonce[
951                                             (wsi->u.ws.frame_mask_index++) & 3];
952
953                 if (--wsi->u.ws.rx_packet_length == 0) {
954                         /* spill because we have the whole frame */
955                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
956                         goto spill;
957                 }
958
959                 /*
960                  * if there's no protocol max frame size given, we are
961                  * supposed to default to LWS_MAX_SOCKET_IO_BUF
962                  */
963
964                 if (!wsi->protocol->rx_buffer_size &&
965                                         wsi->u.ws.rx_user_buffer_head !=
966                                                           LWS_MAX_SOCKET_IO_BUF)
967                         break;
968                 else
969                         if (wsi->protocol->rx_buffer_size &&
970                                         wsi->u.ws.rx_user_buffer_head !=
971                                                   wsi->protocol->rx_buffer_size)
972                         break;
973
974                 /* spill because we filled our rx buffer */
975 spill:
976                 /*
977                  * is this frame a control packet we should take care of at this
978                  * layer?  If so service it and hide it from the user callback
979                  */
980
981                 lwsl_parser("spill on %s\n", wsi->protocol->name);
982
983                 switch (wsi->u.ws.opcode) {
984                 case LWSWSOPC_CLOSE:
985
986                         /* is this an acknowledgement of our close? */
987                         if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
988                                 /*
989                                  * fine he has told us he is closing too, let's
990                                  * finish our close
991                                  */
992                                 lwsl_parser("seen client close ack\n");
993                                 return -1;
994                         }
995                         if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
996                                 /* if he sends us 2 CLOSE, kill him */
997                                 return -1;
998
999                         if (user_callback_handle_rxflow(
1000                                         wsi->protocol->callback, wsi,
1001                                         LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
1002                                         wsi->user_space,
1003                                         &wsi->u.ws.rx_user_buffer[
1004                                                 LWS_SEND_BUFFER_PRE_PADDING],
1005                                         wsi->u.ws.rx_user_buffer_head))
1006                                 return -1;
1007
1008                         lwsl_parser("server sees client close packet\n");
1009                         wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
1010                         /* deal with the close packet contents as a PONG */
1011                         wsi->u.ws.payload_is_close = 1;
1012                         goto process_as_ping;
1013
1014                 case LWSWSOPC_PING:
1015                         lwsl_info("received %d byte ping, sending pong\n",
1016                                                  wsi->u.ws.rx_user_buffer_head);
1017
1018                         if (wsi->u.ws.ping_pending_flag) {
1019                                 /*
1020                                  * there is already a pending ping payload
1021                                  * we should just log and drop
1022                                  */
1023                                 lwsl_parser("DROP PING since one pending\n");
1024                                 goto ping_drop;
1025                         }
1026 process_as_ping:
1027                         /* control packets can only be < 128 bytes long */
1028                         if (wsi->u.ws.rx_user_buffer_head > 128 - 4) {
1029                                 lwsl_parser("DROP PING payload too large\n");
1030                                 goto ping_drop;
1031                         }
1032
1033                         /* stash the pong payload */
1034                         memcpy(wsi->u.ws.ping_payload_buf + LWS_SEND_BUFFER_PRE_PADDING,
1035                                &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1036                                 wsi->u.ws.rx_user_buffer_head);
1037
1038                         wsi->u.ws.ping_payload_len = wsi->u.ws.rx_user_buffer_head;
1039                         wsi->u.ws.ping_pending_flag = 1;
1040
1041                         /* get it sent as soon as possible */
1042                         lws_callback_on_writable(wsi);
1043 ping_drop:
1044                         wsi->u.ws.rx_user_buffer_head = 0;
1045                         return 0;
1046
1047                 case LWSWSOPC_PONG:
1048                         lwsl_info("received pong\n");
1049                         lwsl_hexdump(&wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
1050                                      wsi->u.ws.rx_user_buffer_head);
1051
1052                         /* issue it */
1053                         callback_action = LWS_CALLBACK_RECEIVE_PONG;
1054                         break;
1055
1056                 case LWSWSOPC_TEXT_FRAME:
1057                 case LWSWSOPC_BINARY_FRAME:
1058                 case LWSWSOPC_CONTINUATION:
1059                         break;
1060
1061                 default:
1062                         lwsl_parser("passing opc %x up to exts\n",
1063                                                         wsi->u.ws.opcode);
1064                         /*
1065                          * It's something special we can't understand here.
1066                          * Pass the payload up to the extension's parsing
1067                          * state machine.
1068                          */
1069
1070                         eff_buf.token = &wsi->u.ws.rx_user_buffer[
1071                                                    LWS_SEND_BUFFER_PRE_PADDING];
1072                         eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
1073
1074                         if (lws_ext_cb_wsi_active_exts(wsi,
1075                                 LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
1076                                         &eff_buf, 0) <= 0) /* not handle or fail */
1077                                 lwsl_ext("ext opc opcode 0x%x unknown\n",
1078                                                               wsi->u.ws.opcode);
1079
1080                         wsi->u.ws.rx_user_buffer_head = 0;
1081                         return 0;
1082                 }
1083
1084                 /*
1085                  * No it's real payload, pass it up to the user callback.
1086                  * It's nicely buffered with the pre-padding taken care of
1087                  * so it can be sent straight out again using lws_write
1088                  */
1089
1090                 eff_buf.token = &wsi->u.ws.rx_user_buffer[
1091                                                 LWS_SEND_BUFFER_PRE_PADDING];
1092                 eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
1093
1094                 if (lws_ext_cb_wsi_active_exts(wsi,
1095                                 LWS_EXT_CALLBACK_PAYLOAD_RX, &eff_buf, 0) < 0)
1096                         return -1;
1097
1098                 if (eff_buf.token_len > 0 ||
1099                     callback_action == LWS_CALLBACK_RECEIVE_PONG) {
1100                         eff_buf.token[eff_buf.token_len] = '\0';
1101
1102                         if (wsi->protocol->callback) {
1103
1104                                 if (callback_action == LWS_CALLBACK_RECEIVE_PONG)
1105                                     lwsl_info("Doing pong callback\n");
1106
1107                                 ret = user_callback_handle_rxflow(
1108                                                 wsi->protocol->callback,
1109                                                 wsi,
1110                                                 (enum lws_callback_reasons)callback_action,
1111                                                 wsi->user_space,
1112                                                 eff_buf.token,
1113                                                 eff_buf.token_len);
1114                         }
1115                         else
1116                                 lwsl_err("No callback on payload spill!\n");
1117                 }
1118
1119                 wsi->u.ws.rx_user_buffer_head = 0;
1120                 break;
1121         }
1122
1123         return ret;
1124
1125 illegal_ctl_length:
1126
1127         lwsl_warn("Control frame with xtended length is illegal\n");
1128         /* kill the connection */
1129         return -1;
1130 }
1131
1132
1133 /**
1134  * lws_remaining_packet_payload() - Bytes to come before "overall"
1135  *                                            rx packet is complete
1136  * @wsi:                Websocket instance (available from user callback)
1137  *
1138  *      This function is intended to be called from the callback if the
1139  *  user code is interested in "complete packets" from the client.
1140  *  libwebsockets just passes through payload as it comes and issues a buffer
1141  *  additionally when it hits a built-in limit.  The LWS_CALLBACK_RECEIVE
1142  *  callback handler can use this API to find out if the buffer it has just
1143  *  been given is the last piece of a "complete packet" from the client --
1144  *  when that is the case lws_remaining_packet_payload() will return
1145  *  0.
1146  *
1147  *  Many protocols won't care becuse their packets are always small.
1148  */
1149
1150 LWS_VISIBLE size_t
1151 lws_remaining_packet_payload(struct lws *wsi)
1152 {
1153         return wsi->u.ws.rx_packet_length;
1154 }