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