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