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