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