c78fb92e6640f4335d2c10fc9d311e09537f02f4
[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 LWS_WARN_UNUSED_RESULT
31 lextable_decode(int pos, char c)
32 {
33         if (c >= 'A' && c <= 'Z')
34                 c += 'a' - 'A';
35
36         while (1) {
37                 if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */
38                         if ((lextable[pos] & 0x7f) != c)
39                                 return -1;
40                         /* fall thru */
41                         pos++;
42                         if (lextable[pos] == FAIL_CHAR)
43                                 return -1;
44                         return pos;
45                 }
46
47                 if (lextable[pos] == FAIL_CHAR)
48                         return -1;
49
50                 /* b7 = 0, end or 3-byte */
51                 if (lextable[pos] < FAIL_CHAR) /* terminal marker */
52                         return pos;
53
54                 if (lextable[pos] == c) /* goto */
55                         return pos + (lextable[pos + 1]) +
56                                                 (lextable[pos + 2] << 8);
57                 /* fall thru goto */
58                 pos += 3;
59                 /* continue */
60         }
61 }
62
63 void
64 lws_header_table_reset(struct lws *wsi)
65 {
66         struct allocated_headers *ah = wsi->u.hdr.ah;
67
68         /* if we have the idea we're resetting 'our' ah, must be bound to one */
69         assert(ah);
70         /* ah also concurs with ownership */
71         assert(ah->wsi == wsi);
72
73         /* init the ah to reflect no headers or data have appeared yet */
74         memset(ah->frag_index, 0, sizeof(ah->frag_index));
75         ah->nfrag = 0;
76         ah->pos = 0;
77
78         /* and reset the rx state */
79         ah->rxpos = 0;
80         ah->rxlen = 0;
81
82         /* since we will restart the ah, our new headers are not completed */
83         wsi->hdr_parsing_completed = 0;
84
85         /*
86          * if we inherited pending rx (from socket adoption deferred
87          * processing), apply and free it.
88          */
89         if (wsi->u.hdr.preamble_rx) {
90                 memcpy(ah->rx, wsi->u.hdr.preamble_rx, wsi->u.hdr.preamble_rx_len);
91                 ah->rxlen = wsi->u.hdr.preamble_rx_len;
92                 lws_free_set_NULL(wsi->u.hdr.preamble_rx);
93         }
94 }
95
96 int LWS_WARN_UNUSED_RESULT
97 lws_header_table_attach(struct lws *wsi)
98 {
99         struct lws_context *context = wsi->context;
100         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
101         struct lws_pollargs pa;
102         struct lws **pwsi;
103         int n;
104
105         lwsl_info("%s: wsi %p: ah %p (tsi %d)\n", __func__, (void *)wsi,
106                  (void *)wsi->u.hdr.ah, wsi->tsi);
107
108         /* if we are already bound to one, just clear it down */
109         if (wsi->u.hdr.ah) {
110                 lwsl_err("cleardown\n");
111                 goto reset;
112         }
113
114         lws_pt_lock(pt);
115         pwsi = &pt->ah_wait_list;
116         while (*pwsi) {
117                 if (*pwsi == wsi) {
118                         /* if already waiting on list, if no new ah just ret */
119                         if (pt->ah_count_in_use ==
120                             context->max_http_header_pool) {
121                                 lwsl_err("ah wl denied\n");
122                                 goto bail;
123                         }
124                         /* new ah.... remove ourselves from waiting list */
125                         *pwsi = wsi->u.hdr.ah_wait_list;
126                         wsi->u.hdr.ah_wait_list = NULL;
127                         pt->ah_wait_list_length--;
128                         break;
129                 }
130                 pwsi = &(*pwsi)->u.hdr.ah_wait_list;
131         }
132         /*
133          * pool is all busy... add us to waiting list and return that we
134          * weren't able to deliver it right now
135          */
136         if (pt->ah_count_in_use == context->max_http_header_pool) {
137                 lwsl_info("%s: adding %p to ah waiting list\n", __func__, wsi);
138                 wsi->u.hdr.ah_wait_list = pt->ah_wait_list;
139                 pt->ah_wait_list = wsi;
140                 pt->ah_wait_list_length++;
141
142                 /* we cannot accept input then */
143
144                 _lws_change_pollfd(wsi, LWS_POLLIN, 0, &pa);
145                 goto bail;
146         }
147
148         for (n = 0; n < context->max_http_header_pool; n++)
149                 if (!pt->ah_pool[n].in_use)
150                         break;
151
152         /* if the count of in use said something free... */
153         assert(n != context->max_http_header_pool);
154
155         wsi->u.hdr.ah = &pt->ah_pool[n];
156         wsi->u.hdr.ah->in_use = 1;
157         pt->ah_pool[n].wsi = wsi; /* mark our owner */
158         pt->ah_count_in_use++;
159
160         _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
161
162         lwsl_info("%s: wsi %p: ah %p: count %d (on exit)\n", __func__,
163                   (void *)wsi, (void *)wsi->u.hdr.ah, pt->ah_count_in_use);
164
165         lws_pt_unlock(pt);
166
167 reset:
168         lws_header_table_reset(wsi);
169         time(&wsi->u.hdr.ah->assigned);
170
171         return 0;
172
173 bail:
174         lws_pt_unlock(pt);
175
176         return 1;
177 }
178
179 int lws_header_table_detach(struct lws *wsi)
180 {
181         struct lws_context *context = wsi->context;
182         struct allocated_headers *ah = wsi->u.hdr.ah;
183         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
184         struct lws_pollargs pa;
185         struct lws **pwsi;
186         time_t now;
187
188         lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__,
189                   (void *)wsi, (void *)wsi->u.hdr.ah, wsi->tsi,
190                   pt->ah_count_in_use);
191
192         if (wsi->u.hdr.preamble_rx)
193                 lws_free_set_NULL(wsi->u.hdr.preamble_rx);
194
195         /* may not be detached while he still has unprocessed rx */
196         if (ah && ah->rxpos != ah->rxlen) {
197                 lwsl_err("%s: %p: rxpos:%d, rxlen:%d\n", __func__, wsi,
198                                 ah->rxpos, ah->rxlen);
199                 assert(ah->rxpos == ah->rxlen);
200         }
201
202         lws_pt_lock(pt);
203
204         pwsi = &pt->ah_wait_list;
205         if (!ah) { /* remove from wait list if that's all */
206 //              if (wsi->socket_is_permanently_unusable)
207                         while (*pwsi) {
208                                 if (*pwsi == wsi) {
209                                         lwsl_info("%s: wsi %p, remv wait\n",
210                                                   __func__, wsi);
211                                         *pwsi = wsi->u.hdr.ah_wait_list;
212                                         wsi->u.hdr.ah_wait_list = NULL;
213                                         pt->ah_wait_list_length--;
214                                         goto bail;
215                                 }
216                                 pwsi = &(*pwsi)->u.hdr.ah_wait_list;
217                         }
218
219                 goto bail;
220         }
221         time(&now);
222         if (now - wsi->u.hdr.ah->assigned > 3) {
223                 /*
224                  * we're detaching the ah, but it was held an
225                  * unreasonably long time
226                  */
227                 lwsl_notice("%s: wsi %p: ah held %ds, "
228                             "ah.rxpos %d, ah.rxlen %d, mode/state %d %d,"
229                             "wsi->more_rx_waiting %d\n", __func__, wsi,
230                             (int)(now - wsi->u.hdr.ah->assigned),
231                             ah->rxpos, ah->rxlen, wsi->mode, wsi->state,
232                             wsi->u.hdr.more_rx_waiting);
233         }
234
235         /* if we think we're detaching one, there should be one in use */
236         assert(pt->ah_count_in_use > 0);
237         /* and this specific one should have been in use */
238         assert(wsi->u.hdr.ah->in_use);
239         wsi->u.hdr.ah = NULL;
240         ah->wsi = NULL; /* no owner */
241
242         if (!*pwsi) {
243                 ah->in_use = 0;
244                 pt->ah_count_in_use--;
245
246                 goto bail;
247         }
248
249         /* somebody else on same tsi is waiting, give it to him */
250
251         lwsl_info("pt wait list %p\n", *pwsi);
252         while ((*pwsi)->u.hdr.ah_wait_list)
253                 pwsi = &(*pwsi)->u.hdr.ah_wait_list;
254
255         wsi = *pwsi;
256         lwsl_info("last wsi in wait list %p\n", wsi);
257
258         wsi->u.hdr.ah = ah;
259         ah->wsi = wsi; /* new owner */
260         lws_header_table_reset(wsi);
261         time(&wsi->u.hdr.ah->assigned);
262
263         assert(wsi->position_in_fds_table != -1);
264
265         lwsl_info("%s: Enabling %p POLLIN\n", __func__, wsi);
266
267         /* he has been stuck waiting for an ah, but now his wait is over,
268          * let him progress
269          */
270         _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa);
271
272         /* point prev guy to next guy in list instead */
273         *pwsi = wsi->u.hdr.ah_wait_list;
274         wsi->u.hdr.ah_wait_list = NULL;
275         pt->ah_wait_list_length--;
276
277         assert(!!pt->ah_wait_list_length == !!(int)(long)pt->ah_wait_list);
278 bail:
279         lws_pt_unlock(pt);
280
281         return 0;
282 }
283
284 /**
285  * lws_hdr_fragment_length: report length of a single fragment of a header
286  *              The returned length does not include the space for a
287  *              terminating '\0'
288  *
289  * @wsi: websocket connection
290  * @h: which header index we are interested in
291  * @frag_idx: which fragment of @h we want to get the length of
292  */
293
294 LWS_VISIBLE int
295 lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx)
296 {
297         int n;
298
299         n = wsi->u.hdr.ah->frag_index[h];
300         if (!n)
301                 return 0;
302         do {
303                 if (!frag_idx)
304                         return wsi->u.hdr.ah->frags[n].len;
305                 n = wsi->u.hdr.ah->frags[n].nfrag;
306         } while (frag_idx-- && n);
307
308         return 0;
309 }
310
311 /**
312  * lws_hdr_total_length: report length of all fragments of a header totalled up
313  *              The returned length does not include the space for a
314  *              terminating '\0'
315  *
316  * @wsi: websocket connection
317  * @h: which header index we are interested in
318  */
319
320 LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h)
321 {
322         int n;
323         int len = 0;
324
325         n = wsi->u.hdr.ah->frag_index[h];
326         if (!n)
327                 return 0;
328         do {
329                 len += wsi->u.hdr.ah->frags[n].len;
330                 n = wsi->u.hdr.ah->frags[n].nfrag;
331         } while (n);
332
333         return len;
334 }
335
336 /**
337  * lws_hdr_copy_fragment: copy a single fragment of the given header to a buffer
338  *              The buffer length @len must include space for an additional
339  *              terminating '\0', or it will fail returning -1.
340  *              If the requested fragment index is not present, it fails
341  *              returning -1.
342  *
343  * @wsi: websocket connection
344  * @dst: destination buffer
345  * @len: length of destination buffer
346  * @h: which header index we are interested in
347  * @frag_index: which fragment of @h we want to copy
348  */
349
350 LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
351                                       enum lws_token_indexes h, int frag_idx)
352 {
353         int n = 0;
354         int f = wsi->u.hdr.ah->frag_index[h];
355
356         if (!f)
357                 return -1;
358
359         while (n < frag_idx) {
360                 f = wsi->u.hdr.ah->frags[f].nfrag;
361                 if (!f)
362                         return -1;
363                 n++;
364         }
365
366         if (wsi->u.hdr.ah->frags[f].len >= len)
367                 return -1;
368
369         memcpy(dst, wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[f].offset,
370                wsi->u.hdr.ah->frags[f].len);
371         dst[wsi->u.hdr.ah->frags[f].len] = '\0';
372
373         return wsi->u.hdr.ah->frags[f].len;
374 }
375
376 /**
377  * lws_hdr_copy: copy a single fragment of the given header to a buffer
378  *              The buffer length @len must include space for an additional
379  *              terminating '\0', or it will fail returning -1.
380  *
381  * @wsi: websocket connection
382  * @dst: destination buffer
383  * @len: length of destination buffer
384  * @h: which header index we are interested in
385  */
386
387 LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
388                              enum lws_token_indexes h)
389 {
390         int toklen = lws_hdr_total_length(wsi, h);
391         int n;
392
393         if (toklen >= len)
394                 return -1;
395
396         n = wsi->u.hdr.ah->frag_index[h];
397         if (!n)
398                 return 0;
399
400         do {
401                 strcpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
402                 dst += wsi->u.hdr.ah->frags[n].len;
403                 n = wsi->u.hdr.ah->frags[n].nfrag;
404         } while (n);
405
406         return toklen;
407 }
408
409 char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
410 {
411         int n;
412
413         n = wsi->u.hdr.ah->frag_index[h];
414         if (!n)
415                 return NULL;
416
417         return wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[n].offset;
418 }
419
420 int LWS_WARN_UNUSED_RESULT
421 lws_pos_in_bounds(struct lws *wsi)
422 {
423         if (wsi->u.hdr.ah->pos < wsi->context->max_http_header_data)
424                 return 0;
425
426         if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
427                 lwsl_err("Ran out of header data space\n");
428                 return 1;
429         }
430
431         /*
432          * with these tests everywhere, it should never be able to exceed
433          * the limit, only meet the limit
434          */
435
436         lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->u.hdr.ah->pos,
437                  wsi->context->max_http_header_data);
438         assert(0);
439
440         return 1;
441 }
442
443 int LWS_WARN_UNUSED_RESULT
444 lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s)
445 {
446         wsi->u.hdr.ah->nfrag++;
447         if (wsi->u.hdr.ah->nfrag == ARRAY_SIZE(wsi->u.hdr.ah->frags)) {
448                 lwsl_warn("More hdr frags than we can deal with, dropping\n");
449                 return -1;
450         }
451
452         wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->nfrag;
453
454         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].offset = wsi->u.hdr.ah->pos;
455         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len = 0;
456         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].nfrag = 0;
457
458         do {
459                 if (lws_pos_in_bounds(wsi))
460                         return -1;
461
462                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s;
463                 if (*s)
464                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
465         } while (*s++);
466
467         return 0;
468 }
469
470 static signed char char_to_hex(const char c)
471 {
472         if (c >= '0' && c <= '9')
473                 return c - '0';
474
475         if (c >= 'a' && c <= 'f')
476                 return c - 'a' + 10;
477
478         if (c >= 'A' && c <= 'F')
479                 return c - 'A' + 10;
480
481         return -1;
482 }
483
484 static int LWS_WARN_UNUSED_RESULT
485 issue_char(struct lws *wsi, unsigned char c)
486 {
487         unsigned short frag_len;
488
489         if (lws_pos_in_bounds(wsi))
490                 return -1;
491
492         frag_len = wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len;
493         /*
494          * If we haven't hit the token limit, just copy the character into
495          * the header
496          */
497         if (frag_len < wsi->u.hdr.current_token_limit) {
498                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
499                 if (c)
500                         wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
501                 return 0;
502         }
503
504         /* Insert a null character when we *hit* the limit: */
505         if (frag_len == wsi->u.hdr.current_token_limit) {
506                 if (lws_pos_in_bounds(wsi))
507                         return -1;
508                 wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
509                 lwsl_warn("header %i exceeds limit %d\n",
510                           wsi->u.hdr.parser_state,
511                           wsi->u.hdr.current_token_limit);
512         }
513
514         return 1;
515 }
516
517 int LWS_WARN_UNUSED_RESULT
518 lws_parse(struct lws *wsi, unsigned char c)
519 {
520         static const unsigned char methods[] = {
521                 WSI_TOKEN_GET_URI,
522                 WSI_TOKEN_POST_URI,
523                 WSI_TOKEN_OPTIONS_URI,
524                 WSI_TOKEN_PUT_URI,
525                 WSI_TOKEN_PATCH_URI,
526                 WSI_TOKEN_DELETE_URI,
527         };
528         struct allocated_headers *ah = wsi->u.hdr.ah;
529         struct lws_context *context = wsi->context;
530         unsigned int n, m, enc = 0;
531
532         assert(wsi->u.hdr.ah);
533
534         switch (wsi->u.hdr.parser_state) {
535         default:
536
537                 lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
538
539                 /* collect into malloc'd buffers */
540                 /* optional initial space swallow */
541                 if (!ah->frags[ah->frag_index[wsi->u.hdr.parser_state]].len &&
542                     c == ' ')
543                         break;
544
545                 for (m = 0; m < ARRAY_SIZE(methods); m++)
546                         if (wsi->u.hdr.parser_state == methods[m])
547                                 break;
548                 if (m == ARRAY_SIZE(methods))
549                         /* it was not any of the methods */
550                         goto check_eol;
551
552                 /* special URI processing... end at space */
553
554                 if (c == ' ') {
555                         /* enforce starting with / */
556                         if (!ah->frags[ah->nfrag].len)
557                                 if (issue_char(wsi, '/') < 0)
558                                         return -1;
559
560                         /* begin parsing HTTP version: */
561                         if (issue_char(wsi, '\0') < 0)
562                                 return -1;
563                         wsi->u.hdr.parser_state = WSI_TOKEN_HTTP;
564                         goto start_fragment;
565                 }
566
567                 /* special URI processing... convert %xx */
568
569                 switch (wsi->u.hdr.ues) {
570                 case URIES_IDLE:
571                         if (c == '%') {
572                                 wsi->u.hdr.ues = URIES_SEEN_PERCENT;
573                                 goto swallow;
574                         }
575                         break;
576                 case URIES_SEEN_PERCENT:
577                         if (char_to_hex(c) < 0) {
578                                 /* regurgitate */
579                                 if (issue_char(wsi, '%') < 0)
580                                         return -1;
581                                 wsi->u.hdr.ues = URIES_IDLE;
582                                 /* continue on to assess c */
583                                 break;
584                         }
585                         wsi->u.hdr.esc_stash = c;
586                         wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
587                         goto swallow;
588
589                 case URIES_SEEN_PERCENT_H1:
590                         if (char_to_hex(c) < 0) {
591                                 /* regurgitate */
592                                 if (issue_char(wsi, '%') < 0)
593                                         return -1;
594                                 wsi->u.hdr.ues = URIES_IDLE;
595                                 /* regurgitate + assess */
596                                 if (lws_parse(wsi, wsi->u.hdr.esc_stash) < 0)
597                                         return -1;
598                                 /* continue on to assess c */
599                                 break;
600                         }
601                         c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
602                                         char_to_hex(c);
603                         enc = 1;
604                         wsi->u.hdr.ues = URIES_IDLE;
605                         break;
606                 }
607
608                 /*
609                  * special URI processing...
610                  *  convert /.. or /... or /../ etc to /
611                  *  convert /./ to /
612                  *  convert // or /// etc to /
613                  *  leave /.dir or whatever alone
614                  */
615
616                 switch (wsi->u.hdr.ups) {
617                 case URIPS_IDLE:
618                         if (!c)
619                                 return -1;
620                         /* genuine delimiter */
621                         if ((c == '&' || c == ';') && !enc) {
622                                 if (issue_char(wsi, c) < 0)
623                                         return -1;
624                                 /* swallow the terminator */
625                                 ah->frags[ah->nfrag].len--;
626                                 /* link to next fragment */
627                                 ah->frags[ah->nfrag].nfrag = ah->nfrag + 1;
628                                 ah->nfrag++;
629                                 if (ah->nfrag >= ARRAY_SIZE(ah->frags))
630                                         goto excessive;
631                                 /* start next fragment after the & */
632                                 wsi->u.hdr.post_literal_equal = 0;
633                                 ah->frags[ah->nfrag].offset = ah->pos;
634                                 ah->frags[ah->nfrag].len = 0;
635                                 ah->frags[ah->nfrag].nfrag = 0;
636                                 goto swallow;
637                         }
638                         /* uriencoded = in the name part, disallow */
639                         if (c == '=' && enc && !wsi->u.hdr.post_literal_equal)
640                                 c = '_';
641
642                         /* after the real =, we don't care how many = */
643                         if (c == '=' && !enc)
644                                 wsi->u.hdr.post_literal_equal = 1;
645
646                         /* + to space */
647                         if (c == '+' && !enc)
648                                 c = ' ';
649                         /* issue the first / always */
650                         if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS])
651                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
652                         break;
653                 case URIPS_SEEN_SLASH:
654                         /* swallow subsequent slashes */
655                         if (c == '/')
656                                 goto swallow;
657                         /* track and swallow the first . after / */
658                         if (c == '.') {
659                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT;
660                                 goto swallow;
661                         }
662                         wsi->u.hdr.ups = URIPS_IDLE;
663                         break;
664                 case URIPS_SEEN_SLASH_DOT:
665                         /* swallow second . */
666                         if (c == '.') {
667                                 /*
668                                  * back up one dir level if possible
669                                  * safe against header fragmentation because
670                                  * the method URI can only be in 1 fragment
671                                  */
672                                 if (ah->frags[ah->nfrag].len > 2) {
673                                         ah->pos--;
674                                         ah->frags[ah->nfrag].len--;
675                                         do {
676                                                 ah->pos--;
677                                                 ah->frags[ah->nfrag].len--;
678                                         } while (ah->frags[ah->nfrag].len > 1 &&
679                                                  ah->data[ah->pos] != '/');
680                                 }
681                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
682                                 goto swallow;
683                         }
684                         /* change /./ to / */
685                         if (c == '/') {
686                                 wsi->u.hdr.ups = URIPS_SEEN_SLASH;
687                                 goto swallow;
688                         }
689                         /* it was like /.dir ... regurgitate the . */
690                         wsi->u.hdr.ups = URIPS_IDLE;
691                         if (issue_char(wsi, '.') < 0)
692                                 return -1;
693                         break;
694
695                 case URIPS_SEEN_SLASH_DOT_DOT:
696                         /* swallow prior .. chars and any subsequent . */
697                         if (c == '.')
698                                 goto swallow;
699                         /* last issued was /, so another / == // */
700                         if (c == '/')
701                                 goto swallow;
702                         /* last we issued was / so SEEN_SLASH */
703                         wsi->u.hdr.ups = URIPS_SEEN_SLASH;
704                         break;
705                 }
706
707                 if (c == '?' && !enc &&
708                     !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */
709                         /* seal off uri header */
710                         if (issue_char(wsi, '\0') < 0)
711                                 return -1;
712
713                         /* move to using WSI_TOKEN_HTTP_URI_ARGS */
714                         ah->nfrag++;
715                         if (ah->nfrag >= ARRAY_SIZE(ah->frags))
716                                 goto excessive;
717                         ah->frags[ah->nfrag].offset = ah->pos;
718                         ah->frags[ah->nfrag].len = 0;
719                         ah->frags[ah->nfrag].nfrag = 0;
720
721                         wsi->u.hdr.post_literal_equal = 0;
722                         ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag;
723                         wsi->u.hdr.ups = URIPS_IDLE;
724                         goto swallow;
725                 }
726
727 check_eol:
728
729                 /* bail at EOL */
730                 if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE &&
731                     c == '\x0d') {
732                         c = '\0';
733                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
734                         lwsl_parser("*\n");
735                 }
736
737                 n = issue_char(wsi, c);
738                 if ((int)n < 0)
739                         return -1;
740                 if (n > 0)
741                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
742
743 swallow:
744                 /* per-protocol end of headers management */
745
746                 if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
747                         goto set_parsing_complete;
748                 break;
749
750                 /* collecting and checking a name part */
751         case WSI_TOKEN_NAME_PART:
752                 lwsl_parser("WSI_TOKEN_NAME_PART '%c' (mode=%d)\n", c, wsi->mode);
753
754                 wsi->u.hdr.lextable_pos =
755                                 lextable_decode(wsi->u.hdr.lextable_pos, c);
756                 /*
757                  * Server needs to look out for unknown methods...
758                  */
759                 if (wsi->u.hdr.lextable_pos < 0 &&
760                     wsi->mode == LWSCM_HTTP_SERVING) {
761                         /* this is not a header we know about */
762                         for (m = 0; m < ARRAY_SIZE(methods); m++)
763                                 if (ah->frag_index[methods[m]]) {
764                                         /*
765                                          * already had the method, no idea what
766                                          * this crap from the client is, ignore
767                                          */
768                                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
769                                         break;
770                                 }
771                         /*
772                          * hm it's an unknown http method from a client in fact,
773                          * treat as dangerous
774                          */
775                         if (m == ARRAY_SIZE(methods)) {
776                                 lwsl_info("Unknown method - dropping\n");
777                                 return -1;
778                         }
779                         break;
780                 }
781                 /*
782                  * ...otherwise for a client, let him ignore unknown headers
783                  * coming from the server
784                  */
785                 if (wsi->u.hdr.lextable_pos < 0) {
786                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
787                         break;
788                 }
789
790                 if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
791                         /* terminal state */
792
793                         n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
794                                         lextable[wsi->u.hdr.lextable_pos + 1];
795
796                         lwsl_parser("known hdr %d\n", n);
797                         for (m = 0; m < ARRAY_SIZE(methods); m++)
798                                 if (n == methods[m] &&
799                                     ah->frag_index[methods[m]]) {
800                                         lwsl_warn("Duplicated method\n");
801                                         return -1;
802                                 }
803
804                         /*
805                          * WSORIGIN is protocol equiv to ORIGIN,
806                          * JWebSocket likes to send it, map to ORIGIN
807                          */
808                         if (n == WSI_TOKEN_SWORIGIN)
809                                 n = WSI_TOKEN_ORIGIN;
810
811                         wsi->u.hdr.parser_state = (enum lws_token_indexes)
812                                                         (WSI_TOKEN_GET_URI + n);
813
814                         if (context->token_limits)
815                                 wsi->u.hdr.current_token_limit =
816                                         context->token_limits->token_limit[
817                                                        wsi->u.hdr.parser_state];
818                         else
819                                 wsi->u.hdr.current_token_limit =
820                                         wsi->context->max_http_header_data;
821
822                         if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
823                                 goto set_parsing_complete;
824
825                         goto start_fragment;
826                 }
827                 break;
828
829 start_fragment:
830                 ah->nfrag++;
831 excessive:
832                 if (ah->nfrag == ARRAY_SIZE(ah->frags)) {
833                         lwsl_warn("More hdr frags than we can deal with\n");
834                         return -1;
835                 }
836
837                 ah->frags[ah->nfrag].offset = ah->pos;
838                 ah->frags[ah->nfrag].len = 0;
839                 ah->frags[ah->nfrag].nfrag = 0;
840
841                 n = ah->frag_index[wsi->u.hdr.parser_state];
842                 if (!n) { /* first fragment */
843                         ah->frag_index[wsi->u.hdr.parser_state] = ah->nfrag;
844                         break;
845                 }
846                 /* continuation */
847                 while (ah->frags[n].nfrag)
848                         n = ah->frags[n].nfrag;
849                 ah->frags[n].nfrag = ah->nfrag;
850
851                 if (issue_char(wsi, ' ') < 0)
852                         return -1;
853                 break;
854
855                 /* skipping arg part of a name we didn't recognize */
856         case WSI_TOKEN_SKIPPING:
857                 lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
858
859                 if (c == '\x0d')
860                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
861                 break;
862
863         case WSI_TOKEN_SKIPPING_SAW_CR:
864                 lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
865                 if (c == '\x0a') {
866                         wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
867                         wsi->u.hdr.lextable_pos = 0;
868                 } else
869                         wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
870                 break;
871                 /* we're done, ignore anything else */
872
873         case WSI_PARSING_COMPLETE:
874                 lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c);
875                 break;
876         }
877
878         return 0;
879
880 set_parsing_complete:
881
882         if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
883                 if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
884                         wsi->ietf_spec_revision =
885                                atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
886
887                 lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision);
888         }
889         wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
890         wsi->hdr_parsing_completed = 1;
891
892         return 0;
893 }
894
895
896 /**
897  * lws_frame_is_binary: true if the current frame was sent in binary mode
898  *
899  * @wsi: the connection we are inquiring about
900  *
901  * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if
902  * it's interested to see if the frame it's dealing with was sent in binary
903  * mode.
904  */
905
906 LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi)
907 {
908         return wsi->u.ws.frame_is_binary;
909 }
910
911 int
912 lws_rx_sm(struct lws *wsi, unsigned char c)
913 {
914         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
915         int callback_action = LWS_CALLBACK_RECEIVE;
916         int ret = 0, n, rx_draining_ext = 0;
917         struct lws_tokens eff_buf;
918
919         if (wsi->socket_is_permanently_unusable)
920                 return -1;
921
922         switch (wsi->lws_rx_parse_state) {
923         case LWS_RXPS_NEW:
924                 if (wsi->u.ws.rx_draining_ext) {
925                         struct lws **w = &pt->rx_draining_ext_list;
926
927                         eff_buf.token = NULL;
928                         eff_buf.token_len = 0;
929                         wsi->u.ws.rx_draining_ext = 0;
930                         /* remove us from context draining ext list */
931                         while (*w) {
932                                 if (*w == wsi) {
933                                         *w = wsi->u.ws.rx_draining_ext_list;
934                                         break;
935                                 }
936                                 w = &((*w)->u.ws.rx_draining_ext_list);
937                         }
938                         wsi->u.ws.rx_draining_ext_list = NULL;
939                         rx_draining_ext = 1;
940                         lwsl_err("%s: doing draining flow\n", __func__);
941
942                         goto drain_extension;
943                 }
944                 switch (wsi->ietf_spec_revision) {
945                 case 13:
946                         /*
947                          * no prepended frame key any more
948                          */
949                         wsi->u.ws.all_zero_nonce = 1;
950                         goto handle_first;
951
952                 default:
953                         lwsl_warn("lws_rx_sm: unknown spec version %d\n",
954                                                        wsi->ietf_spec_revision);
955                         break;
956                 }
957                 break;
958         case LWS_RXPS_04_mask_1:
959                 wsi->u.ws.mask[1] = c;
960                 if (c)
961                         wsi->u.ws.all_zero_nonce = 0;
962                 wsi->lws_rx_parse_state = LWS_RXPS_04_mask_2;
963                 break;
964         case LWS_RXPS_04_mask_2:
965                 wsi->u.ws.mask[2] = c;
966                 if (c)
967                         wsi->u.ws.all_zero_nonce = 0;
968                 wsi->lws_rx_parse_state = LWS_RXPS_04_mask_3;
969                 break;
970         case LWS_RXPS_04_mask_3:
971                 wsi->u.ws.mask[3] = c;
972                 if (c)
973                         wsi->u.ws.all_zero_nonce = 0;
974
975                 /*
976                  * start from the zero'th byte in the XOR key buffer since
977                  * this is the start of a frame with a new key
978                  */
979
980                 wsi->u.ws.mask_idx = 0;
981
982                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
983                 break;
984
985         /*
986          *  04 logical framing from the spec (all this is masked when incoming
987          *  and has to be unmasked)
988          *
989          * We ignore the possibility of extension data because we don't
990          * negotiate any extensions at the moment.
991          *
992          *    0                   1                   2                   3
993          *    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
994          *   +-+-+-+-+-------+-+-------------+-------------------------------+
995          *   |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
996          *   |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
997          *   |N|V|V|V|       |V|             |   (if payload len==126/127)   |
998          *   | |1|2|3|       |4|             |                               |
999          *   +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
1000          *   |     Extended payload length continued, if payload len == 127  |
1001          *   + - - - - - - - - - - - - - - - +-------------------------------+
1002          *   |                               |         Extension data        |
1003          *   +-------------------------------+ - - - - - - - - - - - - - - - +
1004          *   :                                                               :
1005          *   +---------------------------------------------------------------+
1006          *   :                       Application data                        :
1007          *   +---------------------------------------------------------------+
1008          *
1009          *  We pass payload through to userland as soon as we get it, ignoring
1010          *  FIN.  It's up to userland to buffer it up if it wants to see a
1011          *  whole unfragmented block of the original size (which may be up to
1012          *  2^63 long!)
1013          */
1014
1015         case LWS_RXPS_04_FRAME_HDR_1:
1016 handle_first:
1017
1018                 wsi->u.ws.opcode = c & 0xf;
1019                 wsi->u.ws.rsv = c & 0x70;
1020                 wsi->u.ws.final = !!((c >> 7) & 1);
1021
1022                 switch (wsi->u.ws.opcode) {
1023                 case LWSWSOPC_TEXT_FRAME:
1024                 case LWSWSOPC_BINARY_FRAME:
1025                         wsi->u.ws.rsv_first_msg = (c & 0x70);
1026                         wsi->u.ws.frame_is_binary =
1027                              wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME;
1028                         break;
1029                 case 3:
1030                 case 4:
1031                 case 5:
1032                 case 6:
1033                 case 7:
1034                 case 0xb:
1035                 case 0xc:
1036                 case 0xd:
1037                 case 0xe:
1038                 case 0xf:
1039                         lwsl_info("illegal opcode\n");
1040                         return -1;
1041                 }
1042                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
1043                 break;
1044
1045         case LWS_RXPS_04_FRAME_HDR_LEN:
1046
1047                 wsi->u.ws.this_frame_masked = !!(c & 0x80);
1048
1049                 switch (c & 0x7f) {
1050                 case 126:
1051                         /* control frames are not allowed to have big lengths */
1052                         if (wsi->u.ws.opcode & 8)
1053                                 goto illegal_ctl_length;
1054
1055                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
1056                         break;
1057                 case 127:
1058                         /* control frames are not allowed to have big lengths */
1059                         if (wsi->u.ws.opcode & 8)
1060                                 goto illegal_ctl_length;
1061
1062                         wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
1063                         break;
1064                 default:
1065                         wsi->u.ws.rx_packet_length = c & 0x7f;
1066                         if (wsi->u.ws.this_frame_masked)
1067                                 wsi->lws_rx_parse_state =
1068                                                 LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1069                         else
1070                                 if (wsi->u.ws.rx_packet_length)
1071                                         wsi->lws_rx_parse_state =
1072                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1073                                 else {
1074                                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1075                                         goto spill;
1076                                 }
1077                         break;
1078                 }
1079                 break;
1080
1081         case LWS_RXPS_04_FRAME_HDR_LEN16_2:
1082                 wsi->u.ws.rx_packet_length = c << 8;
1083                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
1084                 break;
1085
1086         case LWS_RXPS_04_FRAME_HDR_LEN16_1:
1087                 wsi->u.ws.rx_packet_length |= c;
1088                 if (wsi->u.ws.this_frame_masked)
1089                         wsi->lws_rx_parse_state =
1090                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1091                 else
1092                         wsi->lws_rx_parse_state =
1093                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1094                 break;
1095
1096         case LWS_RXPS_04_FRAME_HDR_LEN64_8:
1097                 if (c & 0x80) {
1098                         lwsl_warn("b63 of length must be zero\n");
1099                         /* kill the connection */
1100                         return -1;
1101                 }
1102 #if defined __LP64__
1103                 wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
1104 #else
1105                 wsi->u.ws.rx_packet_length = 0;
1106 #endif
1107                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
1108                 break;
1109
1110         case LWS_RXPS_04_FRAME_HDR_LEN64_7:
1111 #if defined __LP64__
1112                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
1113 #endif
1114                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
1115                 break;
1116
1117         case LWS_RXPS_04_FRAME_HDR_LEN64_6:
1118 #if defined __LP64__
1119                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
1120 #endif
1121                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
1122                 break;
1123
1124         case LWS_RXPS_04_FRAME_HDR_LEN64_5:
1125 #if defined __LP64__
1126                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
1127 #endif
1128                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
1129                 break;
1130
1131         case LWS_RXPS_04_FRAME_HDR_LEN64_4:
1132                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
1133                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
1134                 break;
1135
1136         case LWS_RXPS_04_FRAME_HDR_LEN64_3:
1137                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
1138                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
1139                 break;
1140
1141         case LWS_RXPS_04_FRAME_HDR_LEN64_2:
1142                 wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
1143                 wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
1144                 break;
1145
1146         case LWS_RXPS_04_FRAME_HDR_LEN64_1:
1147                 wsi->u.ws.rx_packet_length |= ((size_t)c);
1148                 if (wsi->u.ws.this_frame_masked)
1149                         wsi->lws_rx_parse_state =
1150                                         LWS_RXPS_07_COLLECT_FRAME_KEY_1;
1151                 else
1152                         wsi->lws_rx_parse_state =
1153                                 LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1154                 break;
1155
1156         case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
1157                 wsi->u.ws.mask[0] = c;
1158                 if (c)
1159                         wsi->u.ws.all_zero_nonce = 0;
1160                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
1161                 break;
1162
1163         case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
1164                 wsi->u.ws.mask[1] = c;
1165                 if (c)
1166                         wsi->u.ws.all_zero_nonce = 0;
1167                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
1168                 break;
1169
1170         case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
1171                 wsi->u.ws.mask[2] = c;
1172                 if (c)
1173                         wsi->u.ws.all_zero_nonce = 0;
1174                 wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
1175                 break;
1176
1177         case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
1178                 wsi->u.ws.mask[3] = c;
1179                 if (c)
1180                         wsi->u.ws.all_zero_nonce = 0;
1181                 wsi->lws_rx_parse_state =
1182                                         LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
1183                 wsi->u.ws.mask_idx = 0;
1184                 if (wsi->u.ws.rx_packet_length == 0) {
1185                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1186                         goto spill;
1187                 }
1188                 break;
1189
1190
1191         case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
1192                 assert(wsi->u.ws.rx_ubuf);
1193
1194                 if (wsi->u.ws.rx_ubuf_head + LWS_PRE >=
1195                     wsi->u.ws.rx_ubuf_alloc) {
1196                         lwsl_err("Attempted overflow \n");
1197                         return -1;
1198                 }
1199                 if (wsi->u.ws.all_zero_nonce)
1200                         wsi->u.ws.rx_ubuf[LWS_PRE +
1201                                          (wsi->u.ws.rx_ubuf_head++)] = c;
1202                 else
1203                         wsi->u.ws.rx_ubuf[LWS_PRE +
1204                                (wsi->u.ws.rx_ubuf_head++)] =
1205                                    c ^ wsi->u.ws.mask[
1206                                             (wsi->u.ws.mask_idx++) & 3];
1207
1208                 if (--wsi->u.ws.rx_packet_length == 0) {
1209                         /* spill because we have the whole frame */
1210                         wsi->lws_rx_parse_state = LWS_RXPS_NEW;
1211                         goto spill;
1212                 }
1213
1214                 /*
1215                  * if there's no protocol max frame size given, we are
1216                  * supposed to default to LWS_MAX_SOCKET_IO_BUF
1217                  */
1218
1219                 if (!wsi->protocol->rx_buffer_size &&
1220                                         wsi->u.ws.rx_ubuf_head !=
1221                                                           LWS_MAX_SOCKET_IO_BUF)
1222                         break;
1223                 else
1224                         if (wsi->protocol->rx_buffer_size &&
1225                                         wsi->u.ws.rx_ubuf_head !=
1226                                                   wsi->protocol->rx_buffer_size)
1227                         break;
1228
1229                 /* spill because we filled our rx buffer */
1230 spill:
1231                 /*
1232                  * is this frame a control packet we should take care of at this
1233                  * layer?  If so service it and hide it from the user callback
1234                  */
1235
1236                 lwsl_parser("spill on %s\n", wsi->protocol->name);
1237
1238                 switch (wsi->u.ws.opcode) {
1239                 case LWSWSOPC_CLOSE:
1240
1241                         /* is this an acknowledgement of our close? */
1242                         if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
1243                                 /*
1244                                  * fine he has told us he is closing too, let's
1245                                  * finish our close
1246                                  */
1247                                 lwsl_parser("seen client close ack\n");
1248                                 return -1;
1249                         }
1250                         if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
1251                                 /* if he sends us 2 CLOSE, kill him */
1252                                 return -1;
1253
1254                         if (user_callback_handle_rxflow(
1255                                         wsi->protocol->callback, wsi,
1256                                         LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
1257                                         wsi->user_space,
1258                                         &wsi->u.ws.rx_ubuf[LWS_PRE],
1259                                         wsi->u.ws.rx_ubuf_head))
1260                                 return -1;
1261
1262                         lwsl_parser("server sees client close packet\n");
1263                         wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
1264                         /* deal with the close packet contents as a PONG */
1265                         wsi->u.ws.payload_is_close = 1;
1266                         goto process_as_ping;
1267
1268                 case LWSWSOPC_PING:
1269                         lwsl_info("received %d byte ping, sending pong\n",
1270                                                  wsi->u.ws.rx_ubuf_head);
1271
1272                         if (wsi->u.ws.ping_pending_flag) {
1273                                 /*
1274                                  * there is already a pending ping payload
1275                                  * we should just log and drop
1276                                  */
1277                                 lwsl_parser("DROP PING since one pending\n");
1278                                 goto ping_drop;
1279                         }
1280 process_as_ping:
1281                         /* control packets can only be < 128 bytes long */
1282                         if (wsi->u.ws.rx_ubuf_head > 128 - 3) {
1283                                 lwsl_parser("DROP PING payload too large\n");
1284                                 goto ping_drop;
1285                         }
1286
1287                         /* stash the pong payload */
1288                         memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE,
1289                                &wsi->u.ws.rx_ubuf[LWS_PRE],
1290                                 wsi->u.ws.rx_ubuf_head);
1291
1292                         wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head;
1293                         wsi->u.ws.ping_pending_flag = 1;
1294
1295                         /* get it sent as soon as possible */
1296                         lws_callback_on_writable(wsi);
1297 ping_drop:
1298                         wsi->u.ws.rx_ubuf_head = 0;
1299                         return 0;
1300
1301                 case LWSWSOPC_PONG:
1302                         lwsl_info("received pong\n");
1303                         lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE],
1304                                      wsi->u.ws.rx_ubuf_head);
1305
1306                         /* issue it */
1307                         callback_action = LWS_CALLBACK_RECEIVE_PONG;
1308                         break;
1309
1310                 case LWSWSOPC_TEXT_FRAME:
1311                 case LWSWSOPC_BINARY_FRAME:
1312                 case LWSWSOPC_CONTINUATION:
1313                         break;
1314
1315                 default:
1316                         lwsl_parser("passing opc %x up to exts\n",
1317                                     wsi->u.ws.opcode);
1318                         /*
1319                          * It's something special we can't understand here.
1320                          * Pass the payload up to the extension's parsing
1321                          * state machine.
1322                          */
1323
1324                         eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
1325                         eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
1326
1327                         if (lws_ext_cb_active(wsi, LWS_EXT_CB_EXTENDED_PAYLOAD_RX,
1328                                         &eff_buf, 0) <= 0) /* not handle or fail */
1329                                 lwsl_ext("ext opc opcode 0x%x unknown\n",
1330                                                               wsi->u.ws.opcode);
1331
1332                         wsi->u.ws.rx_ubuf_head = 0;
1333                         return 0;
1334                 }
1335
1336                 /*
1337                  * No it's real payload, pass it up to the user callback.
1338                  * It's nicely buffered with the pre-padding taken care of
1339                  * so it can be sent straight out again using lws_write
1340                  */
1341
1342                 eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
1343                 eff_buf.token_len = wsi->u.ws.rx_ubuf_head;
1344
1345 drain_extension:
1346                 lwsl_ext("%s: passing %d to ext\n", __func__, eff_buf.token_len);
1347
1348                 if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
1349                     wsi->state == LWSS_AWAITING_CLOSE_ACK)
1350                         goto already_done;
1351
1352                 n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
1353                 if (n < 0) {
1354                         /*
1355                          * we may rely on this to get RX, just drop connection
1356                          */
1357                         wsi->socket_is_permanently_unusable = 1;
1358                         return -1;
1359                 }
1360
1361                 if (rx_draining_ext && eff_buf.token_len == 0)
1362                         goto already_done;
1363
1364                 if (n && eff_buf.token_len) {
1365                         /* extension had more... main loop will come back */
1366                         wsi->u.ws.rx_draining_ext = 1;
1367                         wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list;
1368                         pt->rx_draining_ext_list = wsi;
1369                 }
1370
1371                 if (eff_buf.token_len > 0 ||
1372                     callback_action == LWS_CALLBACK_RECEIVE_PONG) {
1373                         eff_buf.token[eff_buf.token_len] = '\0';
1374
1375                         if (wsi->protocol->callback) {
1376
1377                                 if (callback_action == LWS_CALLBACK_RECEIVE_PONG)
1378                                         lwsl_info("Doing pong callback\n");
1379
1380                                 ret = user_callback_handle_rxflow(
1381                                                 wsi->protocol->callback,
1382                                                 wsi,
1383                                                 (enum lws_callback_reasons)callback_action,
1384                                                 wsi->user_space,
1385                                                 eff_buf.token,
1386                                                 eff_buf.token_len);
1387                         }
1388                         else
1389                                 lwsl_err("No callback on payload spill!\n");
1390                 }
1391
1392 already_done:
1393                 wsi->u.ws.rx_ubuf_head = 0;
1394                 break;
1395         }
1396
1397         return ret;
1398
1399 illegal_ctl_length:
1400
1401         lwsl_warn("Control frame with xtended length is illegal\n");
1402         /* kill the connection */
1403         return -1;
1404 }
1405
1406
1407 /**
1408  * lws_remaining_packet_payload() - Bytes to come before "overall"
1409  *                                            rx packet is complete
1410  * @wsi:                Websocket instance (available from user callback)
1411  *
1412  *      This function is intended to be called from the callback if the
1413  *  user code is interested in "complete packets" from the client.
1414  *  libwebsockets just passes through payload as it comes and issues a buffer
1415  *  additionally when it hits a built-in limit.  The LWS_CALLBACK_RECEIVE
1416  *  callback handler can use this API to find out if the buffer it has just
1417  *  been given is the last piece of a "complete packet" from the client --
1418  *  when that is the case lws_remaining_packet_payload() will return
1419  *  0.
1420  *
1421  *  Many protocols won't care becuse their packets are always small.
1422  */
1423
1424 LWS_VISIBLE size_t
1425 lws_remaining_packet_payload(struct lws *wsi)
1426 {
1427         return wsi->u.ws.rx_packet_length;
1428 }