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