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