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