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