ah try for ah when adopting socket to vhost
[platform/upstream/libwebsockets.git] / lib / server.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2016 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
23 #include "private-libwebsockets.h"
24
25 int
26 lws_context_init_server(struct lws_context_creation_info *info,
27                         struct lws_vhost *vhost)
28 {
29 #ifdef LWS_POSIX
30         int n, opt = 1, limit = 1;
31 #endif
32         lws_sockfd_type sockfd;
33         struct lws_vhost *vh;
34         struct lws *wsi;
35         int m = 0;
36
37         /* set up our external listening socket we serve on */
38
39         if (info->port == CONTEXT_PORT_NO_LISTEN)
40                 return 0;
41
42         vh = vhost->context->vhost_list;
43         while (vh) {
44                 if (vh->listen_port == info->port) {
45                         if ((!info->iface && !vh->iface) ||
46                             (info->iface && vh->iface &&
47                             !strcmp(info->iface, vh->iface))) {
48                                 vhost->listen_port = info->port;
49                                 vhost->iface = info->iface;
50                                 lwsl_notice(" using listen skt from vhost %s\n",
51                                             vh->name);
52                                 return 0;
53                         }
54                 }
55                 vh = vh->vhost_next;
56         }
57
58 #if LWS_POSIX
59 #if defined(__linux__)
60         limit = vhost->context->count_threads;
61 #endif
62
63         for (m = 0; m < limit; m++) {
64 #ifdef LWS_USE_UNIX_SOCK
65         if (LWS_UNIX_SOCK_ENABLED(vhost))
66                 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
67         else
68 #endif
69 #ifdef LWS_USE_IPV6
70         if (LWS_IPV6_ENABLED(context))
71                 sockfd = socket(AF_INET6, SOCK_STREAM, 0);
72         else
73 #endif
74                 sockfd = socket(AF_INET, SOCK_STREAM, 0);
75
76         if (sockfd == -1) {
77 #else
78         sockfd = mbed3_create_tcp_stream_socket();
79         if (!lws_sockfd_valid(sockfd)) {
80 #endif
81                 lwsl_err("ERROR opening socket\n");
82                 return 1;
83         }
84
85 #if LWS_POSIX
86         /*
87          * allow us to restart even if old sockets in TIME_WAIT
88          */
89         if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
90                        (const void *)&opt, sizeof(opt)) < 0) {
91                 compatible_close(sockfd);
92                 return 1;
93         }
94 #if defined(__linux__) && defined(SO_REUSEPORT) && LWS_MAX_SMP > 1
95         if (vhost->context->count_threads > 1)
96                 if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT,
97                                 (const void *)&opt, sizeof(opt)) < 0) {
98                         compatible_close(sockfd);
99                         return 1;
100                 }
101 #endif
102 #endif
103         lws_plat_set_socket_options(vhost, sockfd);
104
105 #if LWS_POSIX
106         n = lws_socket_bind(vhost, sockfd, info->port, info->iface);
107         if (n < 0)
108                 goto bail;
109         info->port = n;
110 #endif
111         vhost->listen_port = info->port;
112         vhost->iface = info->iface;
113
114         wsi = lws_zalloc(sizeof(struct lws));
115         if (wsi == NULL) {
116                 lwsl_err("Out of mem\n");
117                 goto bail;
118         }
119         wsi->context = vhost->context;
120         wsi->sock = sockfd;
121         wsi->mode = LWSCM_SERVER_LISTENER;
122         wsi->protocol = vhost->protocols;
123         wsi->tsi = m;
124         wsi->vhost = vhost;
125         wsi->listener = 1;
126
127         vhost->context->pt[m].wsi_listening = wsi;
128         if (insert_wsi_socket_into_fds(vhost->context, wsi))
129                 goto bail;
130
131         vhost->context->count_wsi_allocated++;
132         vhost->lserv_wsi = wsi;
133
134 #if LWS_POSIX
135         listen(wsi->sock, LWS_SOMAXCONN);
136         } /* for each thread able to independently lister */
137 #else
138         mbed3_tcp_stream_bind(wsi->sock, info->port, wsi);
139 #endif
140         if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) {
141 #ifdef LWS_USE_UNIX_SOCK
142                 if (LWS_UNIX_SOCK_ENABLED(vhost))
143                         lwsl_notice(" Listening on \"%s\"\n", info->iface);
144                 else
145 #endif
146                         lwsl_notice(" Listening on port %d\n", info->port);
147         }
148
149         return 0;
150
151 bail:
152         compatible_close(sockfd);
153
154         return 1;
155 }
156
157 int
158 _lws_server_listen_accept_flow_control(struct lws *twsi, int on)
159 {
160         struct lws_context_per_thread *pt = &twsi->context->pt[(int)twsi->tsi];
161         struct lws *wsi = pt->wsi_listening;
162         int n;
163
164         if (!wsi || twsi->context->being_destroyed)
165                 return 0;
166
167         lwsl_debug("%s: Thr %d: LISTEN wsi %p: state %d\n",
168                    __func__, twsi->tsi, (void *)wsi, on);
169
170         if (on)
171                 n = lws_change_pollfd(wsi, 0, LWS_POLLIN);
172         else
173                 n = lws_change_pollfd(wsi, LWS_POLLIN, 0);
174
175         return n;
176 }
177
178 struct lws_vhost *
179 lws_select_vhost(struct lws_context *context, int port, const char *servername)
180 {
181         struct lws_vhost *vhost = context->vhost_list;
182
183         while (vhost) {
184                 if (port == vhost->listen_port &&
185                     !strcmp(vhost->name, servername)) {
186                         lwsl_info("SNI: Found: %s\n", servername);
187                         return vhost;
188                 }
189                 vhost = vhost->vhost_next;
190         }
191
192         return NULL;
193 }
194
195 static const char * get_mimetype(const char *file)
196 {
197         int n = strlen(file);
198
199         if (n < 5)
200                 return NULL;
201
202         if (!strcmp(&file[n - 4], ".ico"))
203                 return "image/x-icon";
204
205         if (!strcmp(&file[n - 4], ".gif"))
206                 return "image/gif";
207
208         if (!strcmp(&file[n - 3], ".js"))
209                 return "text/javascript";
210
211         if (!strcmp(&file[n - 4], ".png"))
212                 return "image/png";
213
214         if (!strcmp(&file[n - 4], ".jpg"))
215                 return "image/jpeg";
216
217         if (!strcmp(&file[n - 5], ".html"))
218                 return "text/html";
219
220         if (!strcmp(&file[n - 4], ".css"))
221                 return "text/css";
222
223         if (!strcmp(&file[n - 4], ".ttf"))
224                 return "application/x-font-ttf";
225
226         return NULL;
227 }
228
229 int lws_http_serve(struct lws *wsi, char *uri, const char *origin)
230 {
231         const char *mimetype;
232         struct stat st;
233         char path[256], sym[256];
234         int n, spin = 0;
235
236         lwsl_notice("%s: %s %s\n", __func__, uri, origin);
237         snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri);
238
239         do {
240                 spin++;
241
242                 if (stat(path, &st)) {
243                         lwsl_err("unable to stat %s\n", path);
244                         goto bail;
245                 }
246
247                 lwsl_debug(" %s mode %d\n", path, S_IFMT & st.st_mode);
248 #if !defined(WIN32)
249                 if ((S_IFMT & st.st_mode) == S_IFLNK) {
250                         if (readlink(path, sym, sizeof(sym))) {
251                                 lwsl_err("Failed to read link %s\n", path);
252                                 goto bail;
253                         }
254                         lwsl_debug("symlink %s -> %s\n", path, sym);
255                         snprintf(path, sizeof(path) - 1, "%s", sym);
256                 }
257 #endif
258                 if ((S_IFMT & st.st_mode) == S_IFDIR) {
259                         lwsl_debug("default filename append to dir\n");
260                         snprintf(path, sizeof(path) - 1, "%s/%s/index.html",
261                                  origin, uri);
262                 }
263
264         } while ((S_IFMT & st.st_mode) != S_IFREG && spin < 5);
265
266         if (spin == 5) {
267                 lwsl_err("symlink loop %s \n", path);
268         }
269
270         mimetype = get_mimetype(path);
271         if (!mimetype) {
272                 lwsl_err("unknown mimetype for %s", path);
273                 goto bail;
274         }
275
276         n = lws_serve_http_file(wsi, path, mimetype, NULL, 0);
277
278         if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi)))
279                 return -1; /* error or can't reuse connection: close the socket */
280
281         return 0;
282 bail:
283         lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
284
285         return -1;
286 }
287
288 int
289 lws_http_action(struct lws *wsi)
290 {
291         struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
292         enum http_connection_type connection_type;
293         enum http_version request_version;
294         char content_length_str[32];
295         struct lws_http_mount *hm, *hit = NULL;
296         unsigned int n, count = 0;
297         char http_version_str[10];
298         char http_conn_str[20];
299         int http_version_len;
300         char *uri_ptr = NULL;
301         int uri_len = 0, best = 0;
302         int meth = -1;
303
304         static const unsigned char methods[] = {
305                 WSI_TOKEN_GET_URI,
306                 WSI_TOKEN_POST_URI,
307                 WSI_TOKEN_OPTIONS_URI,
308                 WSI_TOKEN_PUT_URI,
309                 WSI_TOKEN_PATCH_URI,
310                 WSI_TOKEN_DELETE_URI,
311 #ifdef LWS_USE_HTTP2
312                 WSI_TOKEN_HTTP_COLON_PATH,
313 #endif
314         };
315 #if defined(_DEBUG) || defined(LWS_WITH_ACCESS_LOG)
316         static const char * const method_names[] = {
317                 "GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE",
318 #ifdef LWS_USE_HTTP2
319                 ":path",
320 #endif
321         };
322 #endif
323
324         /* it's not websocket.... shall we accept it as http? */
325
326         for (n = 0; n < ARRAY_SIZE(methods); n++)
327                 if (lws_hdr_total_length(wsi, methods[n]))
328                         count++;
329         if (!count) {
330                 lwsl_warn("Missing URI in HTTP request\n");
331                 goto bail_nuke_ah;
332         }
333
334         if (count != 1) {
335                 lwsl_warn("multiple methods?\n");
336                 goto bail_nuke_ah;
337         }
338
339         if (lws_ensure_user_space(wsi))
340                 goto bail_nuke_ah;
341
342         for (n = 0; n < ARRAY_SIZE(methods); n++)
343                 if (lws_hdr_total_length(wsi, methods[n])) {
344                         uri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
345                         uri_len = lws_hdr_total_length(wsi, methods[n]);
346                         lwsl_info("Method: %s request for '%s'\n",
347                                         method_names[n], uri_ptr);
348                         meth = n;
349                         break;
350                 }
351
352         (void)meth;
353
354         /* we insist on absolute paths */
355
356         if (uri_ptr[0] != '/') {
357                 lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL);
358
359                 goto bail_nuke_ah;
360         }
361
362         /* HTTP header had a content length? */
363
364         wsi->u.http.content_length = 0;
365         if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) ||
366                 lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) ||
367                 lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI))
368                 wsi->u.http.content_length = 100 * 1024 * 1024;
369
370         if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
371                 lws_hdr_copy(wsi, content_length_str,
372                              sizeof(content_length_str) - 1,
373                              WSI_TOKEN_HTTP_CONTENT_LENGTH);
374                 wsi->u.http.content_length = atoi(content_length_str);
375         }
376
377         if (wsi->http2_substream) {
378                 wsi->u.http.request_version = HTTP_VERSION_2;
379         } else {
380                 /* http_version? Default to 1.0, override with token: */
381                 request_version = HTTP_VERSION_1_0;
382
383                 /* Works for single digit HTTP versions. : */
384                 http_version_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP);
385                 if (http_version_len > 7) {
386                         lws_hdr_copy(wsi, http_version_str,
387                                         sizeof(http_version_str) - 1, WSI_TOKEN_HTTP);
388                         if (http_version_str[5] == '1' && http_version_str[7] == '1')
389                                 request_version = HTTP_VERSION_1_1;
390                 }
391                 wsi->u.http.request_version = request_version;
392
393                 /* HTTP/1.1 defaults to "keep-alive", 1.0 to "close" */
394                 if (request_version == HTTP_VERSION_1_1)
395                         connection_type = HTTP_CONNECTION_KEEP_ALIVE;
396                 else
397                         connection_type = HTTP_CONNECTION_CLOSE;
398
399                 /* Override default if http "Connection:" header: */
400                 if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) {
401                         lws_hdr_copy(wsi, http_conn_str, sizeof(http_conn_str) - 1,
402                                      WSI_TOKEN_CONNECTION);
403                         http_conn_str[sizeof(http_conn_str) - 1] = '\0';
404                         if (!strcasecmp(http_conn_str, "keep-alive"))
405                                 connection_type = HTTP_CONNECTION_KEEP_ALIVE;
406                         else
407                                 if (!strcasecmp(http_conn_str, "close"))
408                                         connection_type = HTTP_CONNECTION_CLOSE;
409                 }
410                 wsi->u.http.connection_type = connection_type;
411         }
412
413         n = wsi->protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION,
414                                     wsi->user_space, uri_ptr, uri_len);
415         if (n) {
416                 lwsl_info("LWS_CALLBACK_HTTP closing\n");
417
418                 return 1;
419         }
420         /*
421          * if there is content supposed to be coming,
422          * put a timeout on it having arrived
423          */
424         lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
425                         wsi->context->timeout_secs);
426 #ifdef LWS_OPENSSL_SUPPORT
427         if (wsi->redirect_to_https) {
428                 /*
429                  * we accepted http:// only so we could redirect to
430                  * https://, so issue the redirect.  Create the redirection
431                  * URI from the host: header and ignore the path part
432                  */
433                 unsigned char *start = pt->serv_buf + LWS_PRE, *p = start,
434                               *end = p + 512;
435
436                 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST))
437                         goto bail_nuke_ah;
438
439                 n = sprintf((char *)end, "https://%s/",
440                             lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
441
442                 n = lws_http_redirect(wsi, end, n, &p, end);
443                 if ((int)n < 0)
444                         goto bail_nuke_ah;
445
446                 return lws_http_transaction_completed(wsi);
447         }
448 #endif
449
450 #ifdef LWS_WITH_ACCESS_LOG
451         /*
452          * Produce Apache-compatible log string for wsi, like this:
453          *
454          * 2.31.234.19 - - [27/Mar/2016:03:22:44 +0800]
455          * "GET /aep-screen.png HTTP/1.1"
456          * 200 152987 "https://libwebsockets.org/index.html"
457          * "Mozilla/5.0 (Macint... Chrome/49.0.2623.87 Safari/537.36"
458          *
459          */
460         {
461                 static const char * const hver[] = {
462                         "http/1.0", "http/1.1", "http/2"
463                 };
464 #ifdef LWS_USE_IPV6
465                 char ads[INET6_ADDRSTRLEN];
466 #else
467                 char ads[INET_ADDRSTRLEN];
468 #endif
469                 char da[64];
470                 const char *pa, *me;
471                 struct tm *tmp;
472                 time_t t = time(NULL);
473                 int l = 256;
474
475                 if (wsi->access_log_pending)
476                         lws_access_log(wsi);
477
478                 wsi->access_log.header_log = lws_malloc(l);
479
480                 tmp = localtime(&t);
481                 if (tmp)
482                         strftime(da, sizeof(da), "%d/%b/%Y:%H:%M:%S %z", tmp);
483                 else
484                         strcpy(da, "01/Jan/1970:00:00:00 +0000");
485
486                 pa = lws_get_peer_simple(wsi, ads, sizeof(ads));
487                 if (!pa)
488                         pa = "(unknown)";
489
490                 if (meth >= 0)
491                         me = method_names[meth];
492                 else
493                         me = "unknown";
494
495                 snprintf(wsi->access_log.header_log, l,
496                          "%s - - [%s] \"%s %s %s\"",
497                          pa, da, me, uri_ptr,
498                          hver[wsi->u.http.request_version]);
499
500                 l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT);
501                 if (l) {
502                         wsi->access_log.user_agent = lws_malloc(l + 2);
503                         lws_hdr_copy(wsi, wsi->access_log.user_agent,
504                                      l + 1, WSI_TOKEN_HTTP_USER_AGENT);
505                 }
506                 wsi->access_log_pending = 1;
507         }
508 #endif
509
510         /* can we serve it from the mount list? */
511
512         hm = wsi->vhost->mount_list;
513         while (hm) {
514                 if (uri_len >= hm->mountpoint_len &&
515                     !strncmp(uri_ptr, hm->mountpoint, hm->mountpoint_len) &&
516                     (uri_ptr[hm->mountpoint_len] == '\0' ||
517                      uri_ptr[hm->mountpoint_len] == '/' ||
518                      hm->mountpoint_len == 1)
519                     ) {
520                         if ((hm->origin_protocol == LWSMPRO_CGI ||
521                              lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) &&
522                             hm->mountpoint_len > best) {
523                                 best = hm->mountpoint_len;
524                                 hit = hm;
525                         }
526                 }
527                 hm = hm->mount_next;
528         }
529         if (hit) {
530                 char *s = uri_ptr + hit->mountpoint_len;
531
532                 lwsl_debug("*** hit %d %d %s\n", hit->mountpoint_len,
533                            hit->origin_protocol , hit->origin);
534
535                 /*
536                  * if we have a mountpoint like https://xxx.com/yyy
537                  * there is an implied / at the end for our purposes since
538                  * we can only mount on a "directory".
539                  *
540                  * But if we just go with that, the browser cannot understand
541                  * that he is actually looking down one "directory level", so
542                  * even though we give him /yyy/abc.html he acts like the
543                  * current directory level is /.  So relative urls like "x.png"
544                  * wrongly look outside the mountpoint.
545                  *
546                  * Therefore if we didn't come in on a url with an explicit
547                  * / at the end, we must redirect to add it so the browser
548                  * understands he is one "directory level" down.
549                  */
550                 if ((hit->mountpoint_len > 1 || (hit->origin_protocol & 4)) &&
551                     (*s != '/' || (hit->origin_protocol & 4)) &&
552                     (hit->origin_protocol != LWSMPRO_CGI)) {
553                         unsigned char *start = pt->serv_buf + LWS_PRE,
554                                               *p = start, *end = p + 512;
555                         static const char *oprot[] = {
556                                 "http://", "https://"
557                         };
558
559                         lwsl_notice("Doing 301 '%s' org %s\n", s, hit->origin);
560
561                         if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST))
562                                 goto bail_nuke_ah;
563
564                         /* > at start indicates deal with by redirect */
565                         if (hit->origin_protocol & 4)
566                                 n = snprintf((char *)end, 256, "%s%s",
567                                             oprot[hit->origin_protocol & 1],
568                                             hit->origin);
569                         else
570                                 n = snprintf((char *)end, 256,
571                                     "https://%s/%s/",
572                                     lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST),
573                                     uri_ptr);
574
575                         n = lws_http_redirect(wsi, end, n, &p, end);
576                         if ((int)n < 0)
577                                 goto bail_nuke_ah;
578
579                         return lws_http_transaction_completed(wsi);
580                 }
581
582 #ifdef LWS_WITH_CGI
583                 /* did we hit something with a cgi:// origin? */
584                 if (hit->origin_protocol == LWSMPRO_CGI) {
585                         const char *cmd[] = {
586                                 NULL, /* replace with cgi path */
587                                 NULL
588                         };
589                         unsigned char *p, *end, buffer[256];
590
591                         lwsl_debug("%s: cgi\n", __func__);
592                         cmd[0] = hit->origin;
593
594                         n = 5;
595                         if (hit->cgi_timeout)
596                                 n = hit->cgi_timeout;
597
598                         n = lws_cgi(wsi, cmd, hit->mountpoint_len, n,
599                                     hit->cgienv);
600                         if (n) {
601                                 lwsl_err("%s: cgi failed\n");
602                                 return -1;
603                         }
604                         p = buffer + LWS_PRE;
605                         end = p + sizeof(buffer) - LWS_PRE;
606
607                         if (lws_add_http_header_status(wsi, 200, &p, end))
608                                 return 1;
609                         if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION,
610                                         (unsigned char *)"close", 5, &p, end))
611                                 return 1;
612                         n = lws_write(wsi, buffer + LWS_PRE,
613                                       p - (buffer + LWS_PRE),
614                                       LWS_WRITE_HTTP_HEADERS);
615
616                         goto deal_body;
617                 }
618 #endif
619
620                 n = strlen(s);
621                 if (s[0] == '\0' || (n == 1 && s[n - 1] == '/'))
622                         s = (char *)hit->def;
623
624                 if (!s)
625                         s = "index.html";
626
627                         // lwsl_err("okok\n");
628
629                 n = lws_http_serve(wsi, s, hit->origin);
630         } else
631                 n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
632                                     wsi->user_space, uri_ptr, uri_len);
633
634         if (n) {
635                 lwsl_info("LWS_CALLBACK_HTTP closing\n");
636
637                 return 1;
638         }
639
640 #ifdef LWS_WITH_CGI
641 deal_body:
642 #endif
643         /*
644          * If we're not issuing a file, check for content_length or
645          * HTTP keep-alive. No keep-alive header allocation for
646          * ISSUING_FILE, as this uses HTTP/1.0.
647          *
648          * In any case, return 0 and let lws_read decide how to
649          * proceed based on state
650          */
651         if (wsi->state != LWSS_HTTP_ISSUING_FILE)
652                 /* Prepare to read body if we have a content length: */
653                 if (wsi->u.http.content_length > 0)
654                         wsi->state = LWSS_HTTP_BODY;
655
656         return 0;
657
658 bail_nuke_ah:
659         /* we're closing, losing some rx is OK */
660         wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
661         lws_header_table_detach(wsi, 1);
662
663         return 1;
664 }
665
666
667 int
668 lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
669 {
670         struct lws_context *context = lws_get_context(wsi);
671         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
672         struct _lws_header_related hdr;
673         struct allocated_headers *ah;
674         int protocol_len, n, hit;
675         char protocol_list[128];
676         char protocol_name[32];
677         char *p;
678
679         assert(len < 10000000);
680         assert(wsi->u.hdr.ah);
681
682         while (len--) {
683                 wsi->more_rx_waiting = !!len;
684
685                 if (wsi->mode != LWSCM_HTTP_SERVING &&
686                     wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED) {
687                         lwsl_err("%s: bad wsi mode %d\n", __func__, wsi->mode);
688                         goto bail_nuke_ah;
689                 }
690
691                 if (lws_parse(wsi, *(*buf)++)) {
692                         lwsl_info("lws_parse failed\n");
693                         goto bail_nuke_ah;
694                 }
695
696                 if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
697                         continue;
698
699                 lwsl_parser("%s: lws_parse sees parsing complete\n", __func__);
700                 lwsl_debug("%s: wsi->more_rx_waiting=%d\n", __func__,
701                                 wsi->more_rx_waiting);
702
703                 /* select vhost */
704
705                 if (lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) {
706                         struct lws_vhost *vhost = lws_select_vhost(
707                                 context, wsi->vhost->listen_port,
708                                 lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST));
709
710                         if (vhost)
711                                 wsi->vhost = vhost;
712                 }
713
714                 wsi->vhost->trans++;
715                 if (!wsi->conn_stat_done) {
716                         wsi->vhost->conn++;
717                         wsi->conn_stat_done = 1;
718                 }
719
720                 wsi->mode = LWSCM_PRE_WS_SERVING_ACCEPT;
721                 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
722
723                 /* is this websocket protocol or normal http 1.0? */
724
725                 if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
726                         if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
727                                         "websocket")) {
728                                 wsi->vhost->ws_upgrades++;
729                                 lwsl_info("Upgrade to ws\n");
730                                 goto upgrade_ws;
731                         }
732 #ifdef LWS_USE_HTTP2
733                         if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
734                                         "h2c")) {
735                                 wsi->vhost->http2_upgrades++;
736                                 lwsl_info("Upgrade to h2c\n");
737                                 goto upgrade_h2c;
738                         }
739 #endif
740                         lwsl_err("Unknown upgrade\n");
741                         /* dunno what he wanted to upgrade to */
742                         goto bail_nuke_ah;
743                 }
744
745                 /* no upgrade ack... he remained as HTTP */
746
747                 lwsl_info("No upgrade\n");
748                 ah = wsi->u.hdr.ah;
749
750                 lws_union_transition(wsi, LWSCM_HTTP_SERVING_ACCEPTED);
751                 wsi->state = LWSS_HTTP;
752                 wsi->u.http.fd = LWS_INVALID_FILE;
753
754                 /* expose it at the same offset as u.hdr */
755                 wsi->u.http.ah = ah;
756                 lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi,
757                            (void *)wsi->u.hdr.ah);
758
759                 n = lws_http_action(wsi);
760
761                 return n;
762
763 #ifdef LWS_USE_HTTP2
764 upgrade_h2c:
765                 if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP2_SETTINGS)) {
766                         lwsl_err("missing http2_settings\n");
767                         goto bail_nuke_ah;
768                 }
769
770                 lwsl_err("h2c upgrade...\n");
771
772                 p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS);
773                 /* convert the peer's HTTP-Settings */
774                 n = lws_b64_decode_string(p, protocol_list,
775                                           sizeof(protocol_list));
776                 if (n < 0) {
777                         lwsl_parser("HTTP2_SETTINGS too long\n");
778                         return 1;
779                 }
780
781                 /* adopt the header info */
782
783                 ah = wsi->u.hdr.ah;
784
785                 lws_union_transition(wsi, LWSCM_HTTP2_SERVING);
786
787                 /* http2 union member has http union struct at start */
788                 wsi->u.http.ah = ah;
789
790                 lws_http2_init(&wsi->u.http2.peer_settings);
791                 lws_http2_init(&wsi->u.http2.my_settings);
792
793                 /* HTTP2 union */
794
795                 lws_http2_interpret_settings_payload(&wsi->u.http2.peer_settings,
796                                 (unsigned char *)protocol_list, n);
797
798                 strcpy(protocol_list,
799                        "HTTP/1.1 101 Switching Protocols\x0d\x0a"
800                       "Connection: Upgrade\x0d\x0a"
801                       "Upgrade: h2c\x0d\x0a\x0d\x0a");
802                 n = lws_issue_raw(wsi, (unsigned char *)protocol_list,
803                                         strlen(protocol_list));
804                 if (n != strlen(protocol_list)) {
805                         lwsl_debug("http2 switch: ERROR writing to socket\n");
806                         return 1;
807                 }
808
809                 wsi->state = LWSS_HTTP2_AWAIT_CLIENT_PREFACE;
810
811                 return 0;
812 #endif
813
814 upgrade_ws:
815                 if (!wsi->protocol)
816                         lwsl_err("NULL protocol at lws_read\n");
817
818                 /*
819                  * It's websocket
820                  *
821                  * Select the first protocol we support from the list
822                  * the client sent us.
823                  *
824                  * Copy it to remove header fragmentation
825                  */
826
827                 if (lws_hdr_copy(wsi, protocol_list, sizeof(protocol_list) - 1,
828                                  WSI_TOKEN_PROTOCOL) < 0) {
829                         lwsl_err("protocol list too long");
830                         goto bail_nuke_ah;
831                 }
832
833                 protocol_len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL);
834                 protocol_list[protocol_len] = '\0';
835                 p = protocol_list;
836                 hit = 0;
837
838                 while (*p && !hit) {
839                         n = 0;
840                         while (n < sizeof(protocol_name) - 1 && *p && *p !=',')
841                                 protocol_name[n++] = *p++;
842                         protocol_name[n] = '\0';
843                         if (*p)
844                                 p++;
845
846                         lwsl_info("checking %s\n", protocol_name);
847
848                         n = 0;
849                         while (wsi->vhost->protocols[n].callback) {
850                                 if (wsi->vhost->protocols[n].name &&
851                                     !strcmp(wsi->vhost->protocols[n].name,
852                                             protocol_name)) {
853                                         wsi->protocol = &wsi->vhost->protocols[n];
854                                         hit = 1;
855                                         break;
856                                 }
857
858                                 n++;
859                         }
860                 }
861
862                 /* we didn't find a protocol he wanted? */
863
864                 if (!hit) {
865                         if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL)) {
866                                 lwsl_err("No protocol from \"%s\" supported\n",
867                                          protocol_list);
868                                 goto bail_nuke_ah;
869                         }
870                         /*
871                          * some clients only have one protocol and
872                          * do not send the protocol list header...
873                          * allow it and match to protocol 0
874                          */
875                         lwsl_info("defaulting to prot 0 handler\n");
876                         n = 0;
877                         wsi->protocol = &wsi->vhost->protocols[0];
878                 }
879
880                 /* allocate wsi->user storage */
881                 if (lws_ensure_user_space(wsi))
882                         goto bail_nuke_ah;
883
884                 /*
885                  * Give the user code a chance to study the request and
886                  * have the opportunity to deny it
887                  */
888                 if ((wsi->protocol->callback)(wsi,
889                                 LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
890                                 wsi->user_space,
891                               lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
892                         lwsl_warn("User code denied connection\n");
893                         goto bail_nuke_ah;
894                 }
895
896                 /*
897                  * Perform the handshake according to the protocol version the
898                  * client announced
899                  */
900
901                 switch (wsi->ietf_spec_revision) {
902                 case 13:
903                         lwsl_parser("lws_parse calling handshake_04\n");
904                         if (handshake_0405(context, wsi)) {
905                                 lwsl_info("hs0405 has failed the connection\n");
906                                 goto bail_nuke_ah;
907                         }
908                         break;
909
910                 default:
911                         lwsl_warn("Unknown client spec version %d\n",
912                                   wsi->ietf_spec_revision);
913                         goto bail_nuke_ah;
914                 }
915
916                 /*
917                  * stitch protocol choice into the vh protocol linked list
918                  * We always insert ourselves at the start of the list
919                  *
920                  * X <-> B
921                  * X <-> pAn <-> pB
922                  */
923                 //lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
924                 //              __func__,
925                 //              wsi->vhost->same_vh_protocol_list[n],
926                 //              wsi->same_vh_protocol_prev);
927                 wsi->same_vh_protocol_prev = /* guy who points to us */
928                         &wsi->vhost->same_vh_protocol_list[n];
929                 wsi->same_vh_protocol_next = /* old first guy is our next */
930                                 wsi->vhost->same_vh_protocol_list[n];
931                 /* we become the new first guy */
932                 wsi->vhost->same_vh_protocol_list[n] = wsi;
933
934                 if (wsi->same_vh_protocol_next)
935                         /* old first guy points back to us now */
936                         wsi->same_vh_protocol_next->same_vh_protocol_prev =
937                                         &wsi->same_vh_protocol_next;
938
939
940
941                 /* we are upgrading to ws, so http/1.1 and keepalive +
942                  * pipelined header considerations about keeping the ah around
943                  * no longer apply.  However it's common for the first ws
944                  * protocol data to have been coalesced with the browser
945                  * upgrade request and to already be in the ah rx buffer.
946                  */
947
948                 lwsl_info("%s: %p: inheriting ah in ws mode (rxpos:%d, rxlen:%d)\n",
949                           __func__, wsi, wsi->u.hdr.ah->rxpos,
950                           wsi->u.hdr.ah->rxlen);
951                 lws_pt_lock(pt);
952                 hdr = wsi->u.hdr;
953
954                 lws_union_transition(wsi, LWSCM_WS_SERVING);
955                 /*
956                  * first service is WS mode will notice this, use the RX and
957                  * then detach the ah (caution: we are not in u.hdr union
958                  * mode any more then... ah_temp member is at start the same
959                  * though)
960                  *
961                  * Because rxpos/rxlen shows something in the ah, we will get
962                  * service guaranteed next time around the event loop
963                  *
964                  * All union members begin with hdr, so we can use it even
965                  * though we transitioned to ws union mode (the ah detach
966                  * code uses it anyway).
967                  */
968                 wsi->u.hdr = hdr;
969                 lws_pt_unlock(pt);
970
971                 /*
972                  * create the frame buffer for this connection according to the
973                  * size mentioned in the protocol definition.  If 0 there, use
974                  * a big default for compatibility
975                  */
976
977                 n = wsi->protocol->rx_buffer_size;
978                 if (!n)
979                         n = LWS_MAX_SOCKET_IO_BUF;
980                 n += LWS_PRE;
981                 wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */);
982                 if (!wsi->u.ws.rx_ubuf) {
983                         lwsl_err("Out of Mem allocating rx buffer %d\n", n);
984                         return 1;
985                 }
986                 wsi->u.ws.rx_ubuf_alloc = n;
987                 lwsl_info("Allocating RX buffer %d\n", n);
988 #if LWS_POSIX
989                 if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF,
990                                (const char *)&n, sizeof n)) {
991                         lwsl_warn("Failed to set SNDBUF to %d", n);
992                         return 1;
993                 }
994 #endif
995                 lwsl_parser("accepted v%02d connection\n",
996                             wsi->ietf_spec_revision);
997
998                 return 0;
999         } /* while all chars are handled */
1000
1001         return 0;
1002
1003 bail_nuke_ah:
1004         /* drop the header info */
1005         /* we're closing, losing some rx is OK */
1006         wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
1007         lws_header_table_detach(wsi, 1);
1008
1009         return 1;
1010 }
1011
1012 static int
1013 lws_get_idlest_tsi(struct lws_context *context)
1014 {
1015         unsigned int lowest = ~0;
1016         int n = 0, hit = -1;
1017
1018         for (; n < context->count_threads; n++) {
1019                 if ((unsigned int)context->pt[n].fds_count !=
1020                     context->fd_limit_per_thread - 1 &&
1021                     (unsigned int)context->pt[n].fds_count < lowest) {
1022                         lowest = context->pt[n].fds_count;
1023                         hit = n;
1024                 }
1025         }
1026
1027         return hit;
1028 }
1029
1030 struct lws *
1031 lws_create_new_server_wsi(struct lws_vhost *vhost)
1032 {
1033         struct lws *new_wsi;
1034         int n = lws_get_idlest_tsi(vhost->context);
1035
1036         if (n < 0) {
1037                 lwsl_err("no space for new conn\n");
1038                 return NULL;
1039         }
1040
1041         new_wsi = lws_zalloc(sizeof(struct lws));
1042         if (new_wsi == NULL) {
1043                 lwsl_err("Out of memory for new connection\n");
1044                 return NULL;
1045         }
1046
1047         new_wsi->tsi = n;
1048         lwsl_info("Accepted %p to tsi %d\n", new_wsi, new_wsi->tsi);
1049
1050         new_wsi->vhost = vhost;
1051         new_wsi->context = vhost->context;
1052         new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
1053         new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW;
1054
1055         /* intialize the instance struct */
1056
1057         new_wsi->state = LWSS_HTTP;
1058         new_wsi->mode = LWSCM_HTTP_SERVING;
1059         new_wsi->hdr_parsing_completed = 0;
1060
1061 #ifdef LWS_OPENSSL_SUPPORT
1062         new_wsi->use_ssl = LWS_SSL_ENABLED(vhost);
1063 #endif
1064
1065         /*
1066          * these can only be set once the protocol is known
1067          * we set an unestablished connection's protocol pointer
1068          * to the start of the supported list, so it can look
1069          * for matching ones during the handshake
1070          */
1071         new_wsi->protocol = vhost->protocols;
1072         new_wsi->user_space = NULL;
1073         new_wsi->ietf_spec_revision = 0;
1074         new_wsi->sock = LWS_SOCK_INVALID;
1075         vhost->context->count_wsi_allocated++;
1076
1077         /*
1078          * outermost create notification for wsi
1079          * no user_space because no protocol selection
1080          */
1081         vhost->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE,
1082                                        NULL, NULL, 0);
1083
1084         return new_wsi;
1085 }
1086
1087 /**
1088  * lws_http_transaction_completed() - wait for new http transaction or close
1089  * @wsi:        websocket connection
1090  *
1091  *      Returns 1 if the HTTP connection must close now
1092  *      Returns 0 and resets connection to wait for new HTTP header /
1093  *        transaction if possible
1094  */
1095
1096 LWS_VISIBLE int LWS_WARN_UNUSED_RESULT
1097 lws_http_transaction_completed(struct lws *wsi)
1098 {
1099         int n = NO_PENDING_TIMEOUT;
1100
1101         lws_access_log(wsi);
1102
1103         lwsl_debug("%s: wsi %p\n", __func__, wsi);
1104         /* if we can't go back to accept new headers, drop the connection */
1105         if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
1106                 lwsl_info("%s: %p: close connection\n", __func__, wsi);
1107                 return 1;
1108         }
1109
1110         /* otherwise set ourselves up ready to go again */
1111         wsi->state = LWSS_HTTP;
1112         wsi->mode = LWSCM_HTTP_SERVING;
1113         wsi->u.http.content_length = 0;
1114         wsi->hdr_parsing_completed = 0;
1115
1116
1117         if (wsi->vhost->keepalive_timeout)
1118                 n = PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE;
1119         lws_set_timeout(wsi, n, wsi->vhost->keepalive_timeout);
1120
1121         /*
1122          * We already know we are on http1.1 / keepalive and the next thing
1123          * coming will be another header set.
1124          *
1125          * If there is no pending rx and we still have the ah, drop it and
1126          * reacquire a new ah when the new headers start to arrive.  (Otherwise
1127          * we needlessly hog an ah indefinitely.)
1128          *
1129          * However if there is pending rx and we know from the keepalive state
1130          * that is already at least the start of another header set, simply
1131          * reset the existing header table and keep it.
1132          */
1133         if (wsi->u.hdr.ah) {
1134                 lwsl_info("%s: wsi->more_rx_waiting=%d\n", __func__,
1135                                 wsi->more_rx_waiting);
1136
1137                 if (!wsi->more_rx_waiting) {
1138                         wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
1139                         lws_header_table_detach(wsi, 1);
1140                 } else
1141                         lws_header_table_reset(wsi, 1);
1142         }
1143
1144         /* If we're (re)starting on headers, need other implied init */
1145         wsi->u.hdr.ues = URIES_IDLE;
1146
1147         lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi);
1148
1149         return 0;
1150 }
1151
1152 static struct lws *
1153 lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd)
1154 {
1155         struct lws_context *context = vh->context;
1156         struct lws *new_wsi = lws_create_new_server_wsi(vh);
1157
1158         if (!new_wsi) {
1159                 compatible_close(accept_fd);
1160                 return NULL;
1161         }
1162
1163         lwsl_info("%s: new wsi %p, sockfd %d\n", __func__, new_wsi, accept_fd);
1164
1165         new_wsi->sock = accept_fd;
1166
1167         /* the transport is accepted... give him time to negotiate */
1168         lws_set_timeout(new_wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
1169                         context->timeout_secs);
1170
1171 #if LWS_POSIX == 0
1172         mbed3_tcp_stream_accept(accept_fd, new_wsi);
1173 #endif
1174
1175         /*
1176          * A new connection was accepted. Give the user a chance to
1177          * set properties of the newly created wsi. There's no protocol
1178          * selected yet so we issue this to protocols[0]
1179          */
1180         if ((context->vhost_list->protocols[0].callback)(new_wsi,
1181              LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0)) {
1182                 compatible_close(new_wsi->sock);
1183                 lws_free(new_wsi);
1184                 return NULL;
1185         }
1186
1187         lws_libev_accept(new_wsi, new_wsi->sock);
1188         lws_libuv_accept(new_wsi, new_wsi->sock);
1189
1190         if (!LWS_SSL_ENABLED(new_wsi->vhost)) {
1191                 if (insert_wsi_socket_into_fds(context, new_wsi)) {
1192                         lwsl_err("%s: fail inserting socket\n", __func__);
1193                         goto fail;
1194                 }
1195         } else {
1196                 new_wsi->mode = LWSCM_SSL_INIT;
1197                 if (lws_server_socket_service_ssl(new_wsi, accept_fd)) {
1198                         lwsl_err("%s: fail ssl negotiation\n", __func__);
1199                         goto fail;
1200                 }
1201         }
1202
1203         if (!lws_header_table_attach(new_wsi, 0))
1204                 lwsl_debug("Attached ah immediately\n");
1205
1206         return new_wsi;
1207
1208 fail:
1209         lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS);
1210
1211         return NULL;
1212 }
1213
1214 /**
1215  * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it
1216  * @context: lws context
1217  * @accept_fd: fd of already-accepted socket to adopt
1218  *
1219  * Either returns new wsi bound to accept_fd, or closes accept_fd and
1220  * returns NULL, having cleaned up any new wsi pieces.
1221  *
1222  * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
1223  * to ws or just serve http.
1224  */
1225
1226 LWS_VISIBLE struct lws *
1227 lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd)
1228 {
1229         return lws_adopt_socket_vhost(context->vhost_list, accept_fd);
1230 }
1231
1232
1233 /**
1234  * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
1235  * @context:    lws context
1236  * @accept_fd:  fd of already-accepted socket to adopt
1237  * @readbuf:    NULL or pointer to data that must be drained before reading from
1238  *              accept_fd
1239  * @len:        The length of the data held at @readbuf
1240  *
1241  * Either returns new wsi bound to accept_fd, or closes accept_fd and
1242  * returns NULL, having cleaned up any new wsi pieces.
1243  *
1244  * LWS adopts the socket in http serving mode, it's ready to accept an upgrade
1245  * to ws or just serve http.
1246  *
1247  * If your external code did not already read from the socket, you can use
1248  * lws_adopt_socket() instead.
1249  *
1250  * This api is guaranteed to use the data at @readbuf first, before reading from
1251  * the socket.
1252  *
1253  * @readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
1254  */
1255
1256 LWS_VISIBLE LWS_EXTERN struct lws *
1257 lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
1258                          const char *readbuf, size_t len)
1259 {
1260         struct lws *wsi = lws_adopt_socket(context, accept_fd);
1261         struct lws_context_per_thread *pt;
1262         struct allocated_headers *ah;
1263         struct lws_pollfd *pfd;
1264
1265         if (!wsi)
1266                 return NULL;
1267
1268         if (!readbuf)
1269                 return wsi;
1270
1271         if (len > sizeof(ah->rx)) {
1272                 lwsl_err("%s: rx in too big\n", __func__);
1273                 goto bail;
1274         }
1275         /*
1276          * we can't process the initial read data until we can attach an ah.
1277          *
1278          * if one is available, get it and place the data in his ah rxbuf...
1279          * wsi with ah that have pending rxbuf get auto-POLLIN service.
1280          *
1281          * no autoservice because we didn't get a chance to attach the
1282          * readbuf data to wsi or ah yet, and we will do it next if we get
1283          * the ah.
1284          */
1285         if (wsi->u.hdr.ah || !lws_header_table_attach(wsi, 0)) {
1286                 ah = wsi->u.hdr.ah;
1287                 memcpy(ah->rx, readbuf, len);
1288                 ah->rxpos = 0;
1289                 ah->rxlen = len;
1290
1291                 lwsl_notice("%s: calling service on readbuf ah\n", __func__);
1292                 pt = &context->pt[(int)wsi->tsi];
1293
1294                 /* unlike a normal connect, we have the headers already
1295                  * (or the first part of them anyway).
1296                  * libuv won't come back and service us without a network
1297                  * event, so we need to do the header service right here.
1298                  */
1299                 pfd = &pt->fds[wsi->position_in_fds_table];
1300                 pfd->revents |= LWS_POLLIN;
1301                 lwsl_err("%s: calling service\n", __func__);
1302                 if (lws_service_fd_tsi(context, pfd, wsi->tsi))
1303                         /* service closed us */
1304                         return NULL;
1305
1306                 return wsi;
1307         }
1308         lwsl_err("%s: deferring handling ah\n", __func__);
1309         /*
1310          * hum if no ah came, we are on the wait list and must defer
1311          * dealing with this until the ah arrives.
1312          *
1313          * later successful lws_header_table_attach() will apply the
1314          * below to the rx buffer (via lws_header_table_reset()).
1315          */
1316         wsi->u.hdr.preamble_rx = lws_malloc(len);
1317         memcpy(wsi->u.hdr.preamble_rx, readbuf, len);
1318         wsi->u.hdr.preamble_rx_len = len;
1319
1320         return wsi;
1321
1322 bail:
1323         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
1324
1325         return NULL;
1326 }
1327
1328 LWS_VISIBLE int
1329 lws_server_socket_service(struct lws_context *context, struct lws *wsi,
1330                           struct lws_pollfd *pollfd)
1331 {
1332         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
1333         lws_sockfd_type accept_fd = LWS_SOCK_INVALID;
1334         struct allocated_headers *ah;
1335 #if LWS_POSIX
1336         struct sockaddr_in cli_addr;
1337         socklen_t clilen;
1338 #endif
1339         int n, len;
1340
1341         switch (wsi->mode) {
1342
1343         case LWSCM_HTTP_SERVING:
1344         case LWSCM_HTTP_SERVING_ACCEPTED:
1345         case LWSCM_HTTP2_SERVING:
1346
1347                 /* handle http headers coming in */
1348
1349                 /* pending truncated sends have uber priority */
1350
1351                 if (wsi->trunc_len) {
1352                         if (!(pollfd->revents & LWS_POLLOUT))
1353                                 break;
1354
1355                         if (lws_issue_raw(wsi, wsi->trunc_alloc +
1356                                                wsi->trunc_offset,
1357                                           wsi->trunc_len) < 0)
1358                                 goto fail;
1359                         /*
1360                          * we can't afford to allow input processing to send
1361                          * something new, so spin around he event loop until
1362                          * he doesn't have any partials
1363                          */
1364                         break;
1365                 }
1366
1367                 /* any incoming data ready? */
1368
1369                 if (!(pollfd->revents & pollfd->events & LWS_POLLIN))
1370                         goto try_pollout;
1371
1372                 /* these states imply we MUST have an ah attached */
1373
1374                 if (wsi->state == LWSS_HTTP ||
1375                     wsi->state == LWSS_HTTP_ISSUING_FILE ||
1376                     wsi->state == LWSS_HTTP_HEADERS) {
1377                         if (!wsi->u.hdr.ah)
1378                                 /* no autoservice beacuse we will do it next */
1379                                 if (lws_header_table_attach(wsi, 0))
1380                                         goto try_pollout;
1381
1382                         ah = wsi->u.hdr.ah;
1383
1384                         lwsl_debug("%s: %p: rxpos:%d rxlen:%d\n", __func__, wsi,
1385                                    ah->rxpos, ah->rxlen);
1386
1387                         /* if nothing in ah rx buffer, get some fresh rx */
1388                         if (ah->rxpos == ah->rxlen) {
1389                                 ah->rxlen = lws_ssl_capable_read(wsi, ah->rx,
1390                                                    sizeof(ah->rx));
1391                                 ah->rxpos = 0;
1392                                 lwsl_debug("%s: wsi %p, ah->rxlen = %d\r\n",
1393                                            __func__, wsi, ah->rxlen);
1394                                 switch (ah->rxlen) {
1395                                 case 0:
1396                                         lwsl_info("%s: read 0 len\n", __func__);
1397                                         /* lwsl_info("   state=%d\n", wsi->state); */
1398 //                                      if (!wsi->hdr_parsing_completed)
1399 //                                              lws_header_table_detach(wsi);
1400                                         /* fallthru */
1401                                 case LWS_SSL_CAPABLE_ERROR:
1402                                         goto fail;
1403                                 case LWS_SSL_CAPABLE_MORE_SERVICE:
1404                                         ah->rxlen = ah->rxpos = 0;
1405                                         goto try_pollout;
1406                                 }
1407                         }
1408                         assert(ah->rxpos != ah->rxlen && ah->rxlen);
1409                         /* just ignore incoming if waiting for close */
1410                         if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
1411                                 n = lws_read(wsi, ah->rx + ah->rxpos,
1412                                              ah->rxlen - ah->rxpos);
1413                                 if (n < 0) /* we closed wsi */
1414                                         return 1;
1415                                 if (wsi->u.hdr.ah) {
1416                                         if ( wsi->u.hdr.ah->rxlen)
1417                                                  wsi->u.hdr.ah->rxpos += n;
1418
1419                                         if (wsi->u.hdr.ah->rxpos == wsi->u.hdr.ah->rxlen &&
1420                                             (wsi->mode != LWSCM_HTTP_SERVING &&
1421                                              wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
1422                                              wsi->mode != LWSCM_HTTP2_SERVING))
1423                                                 lws_header_table_detach(wsi, 1);
1424                                 }
1425                                 break;
1426                         }
1427
1428                         goto try_pollout;
1429                 }
1430
1431                 len = lws_ssl_capable_read(wsi, pt->serv_buf,
1432                                            LWS_MAX_SOCKET_IO_BUF);
1433                 lwsl_debug("%s: wsi %p read %d\r\n", __func__, wsi, len);
1434                 switch (len) {
1435                 case 0:
1436                         lwsl_info("%s: read 0 len\n", __func__);
1437                         /* lwsl_info("   state=%d\n", wsi->state); */
1438 //                      if (!wsi->hdr_parsing_completed)
1439 //                              lws_header_table_detach(wsi);
1440                         /* fallthru */
1441                 case LWS_SSL_CAPABLE_ERROR:
1442                         goto fail;
1443                 case LWS_SSL_CAPABLE_MORE_SERVICE:
1444                         goto try_pollout;
1445                 }
1446
1447                 /* just ignore incoming if waiting for close */
1448                 if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
1449                         /*
1450                          * hm this may want to send
1451                          * (via HTTP callback for example)
1452                          */
1453                         n = lws_read(wsi, pt->serv_buf, len);
1454                         if (n < 0) /* we closed wsi */
1455                                 return 1;
1456                         /* hum he may have used up the
1457                          * writability above */
1458                         break;
1459                 }
1460
1461 try_pollout:
1462                 /* this handles POLLOUT for http serving fragments */
1463
1464                 if (!(pollfd->revents & LWS_POLLOUT))
1465                         break;
1466
1467                 /* one shot */
1468                 if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) {
1469                         lwsl_notice("%s a\n", __func__);
1470                         goto fail;
1471                 }
1472
1473                 if (!wsi->hdr_parsing_completed)
1474                         break;
1475
1476                 if (wsi->state != LWSS_HTTP_ISSUING_FILE) {
1477                         n = user_callback_handle_rxflow(wsi->protocol->callback,
1478                                         wsi, LWS_CALLBACK_HTTP_WRITEABLE,
1479                                         wsi->user_space, NULL, 0);
1480                         if (n < 0) {
1481                                 lwsl_info("writeable_fail\n");
1482                                 goto fail;
1483                         }
1484                         break;
1485                 }
1486
1487                 /* >0 == completion, <0 == error */
1488                 n = lws_serve_http_file_fragment(wsi);
1489                 if (n < 0 || (n > 0 && lws_http_transaction_completed(wsi))) {
1490                         lwsl_info("completed\n");
1491                         goto fail;
1492                 }
1493                 break;
1494
1495         case LWSCM_SERVER_LISTENER:
1496
1497 #if LWS_POSIX
1498                 /* pollin means a client has connected to us then */
1499
1500                 do {
1501                         if (!(pollfd->revents & LWS_POLLIN) || !(pollfd->events & LWS_POLLIN))
1502                                 break;
1503
1504                         /* listen socket got an unencrypted connection... */
1505
1506                         clilen = sizeof(cli_addr);
1507                         lws_latency_pre(context, wsi);
1508                         accept_fd  = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
1509                                             &clilen);
1510                         lws_latency(context, wsi, "listener accept", accept_fd,
1511                                     accept_fd >= 0);
1512                         if (accept_fd < 0) {
1513                                 if (LWS_ERRNO == LWS_EAGAIN ||
1514                                     LWS_ERRNO == LWS_EWOULDBLOCK) {
1515                                         lwsl_err("accept asks to try again\n");
1516                                         break;
1517                                 }
1518                                 lwsl_err("ERROR on accept: %s\n", strerror(LWS_ERRNO));
1519                                 break;
1520                         }
1521
1522                         lws_plat_set_socket_options(wsi->vhost, accept_fd);
1523
1524                         lwsl_debug("accepted new conn  port %u on fd=%d\n",
1525                                           ntohs(cli_addr.sin_port), accept_fd);
1526
1527 #else
1528                         /* not very beautiful... */
1529                         accept_fd = (lws_sockfd_type)pollfd;
1530 #endif
1531                         /*
1532                          * look at who we connected to and give user code a chance
1533                          * to reject based on client IP.  There's no protocol selected
1534                          * yet so we issue this to protocols[0]
1535                          */
1536                         if ((wsi->vhost->protocols[0].callback)(wsi,
1537                                         LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
1538                                         NULL, (void *)(long)accept_fd, 0)) {
1539                                 lwsl_debug("Callback denied network connection\n");
1540                                 compatible_close(accept_fd);
1541                                 break;
1542                         }
1543
1544                         if (!lws_adopt_socket_vhost(wsi->vhost, accept_fd))
1545                                 /* already closed cleanly as necessary */
1546                                 return 1;
1547
1548 #if LWS_POSIX
1549                 } while (pt->fds_count < context->fd_limit_per_thread - 1 &&
1550                          lws_poll_listen_fd(&pt->fds[wsi->position_in_fds_table]) > 0);
1551 #endif
1552                 return 0;
1553
1554         default:
1555                 break;
1556         }
1557
1558         if (!lws_server_socket_service_ssl(wsi, accept_fd))
1559                 return 0;
1560
1561 fail:
1562         lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
1563
1564         return 1;
1565 }
1566
1567 /**
1568  * lws_serve_http_file() - Send a file back to the client using http
1569  * @wsi:                Websocket instance (available from user callback)
1570  * @file:               The file to issue over http
1571  * @content_type:       The http content type, eg, text/html
1572  * @other_headers:      NULL or pointer to header string
1573  * @other_headers_len:  length of the other headers if non-NULL
1574  *
1575  *      This function is intended to be called from the callback in response
1576  *      to http requests from the client.  It allows the callback to issue
1577  *      local files down the http link in a single step.
1578  *
1579  *      Returning <0 indicates error and the wsi should be closed.  Returning
1580  *      >0 indicates the file was completely sent and
1581  *      lws_http_transaction_completed() called on the wsi (and close if != 0)
1582  *      ==0 indicates the file transfer is started and needs more service later,
1583  *      the wsi should be left alone.
1584  */
1585
1586 LWS_VISIBLE int
1587 lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
1588                     const char *other_headers, int other_headers_len)
1589 {
1590         struct lws_context *context = lws_get_context(wsi);
1591         struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
1592         unsigned char *response = pt->serv_buf + LWS_PRE;
1593         unsigned char *p = response;
1594         unsigned char *end = p + LWS_MAX_SOCKET_IO_BUF - LWS_PRE;
1595         int ret = 0;
1596
1597         wsi->u.http.fd = lws_plat_file_open(wsi, file, &wsi->u.http.filelen,
1598                                             O_RDONLY);
1599
1600         if (wsi->u.http.fd == LWS_INVALID_FILE) {
1601                 lwsl_err("Unable to open '%s'\n", file);
1602                 lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
1603
1604                 return -1;
1605         }
1606
1607         if (lws_add_http_header_status(wsi, 200, &p, end))
1608                 return -1;
1609         if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER,
1610                                          (unsigned char *)"libwebsockets", 13,
1611                                          &p, end))
1612                 return -1;
1613         if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
1614                                          (unsigned char *)content_type,
1615                                          strlen(content_type), &p, end))
1616                 return -1;
1617         if (lws_add_http_header_content_length(wsi, wsi->u.http.filelen, &p, end))
1618                 return -1;
1619
1620         if (other_headers) {
1621                 if ((end - p) < other_headers_len)
1622                         return -1;
1623                 memcpy(p, other_headers, other_headers_len);
1624                 p += other_headers_len;
1625         }
1626
1627         if (lws_finalize_http_header(wsi, &p, end))
1628                 return -1;
1629
1630         ret = lws_write(wsi, response, p - response, LWS_WRITE_HTTP_HEADERS);
1631         if (ret != (p - response)) {
1632                 lwsl_err("_write returned %d from %d\n", ret, (p - response));
1633                 return -1;
1634         }
1635
1636         wsi->u.http.filepos = 0;
1637         wsi->state = LWSS_HTTP_ISSUING_FILE;
1638
1639         return lws_serve_http_file_fragment(wsi);
1640 }
1641
1642 int
1643 lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
1644 {
1645         int m;
1646
1647         lwsl_parser("%s: received %d byte packet\n", __func__, (int)len);
1648 #if 0
1649         lwsl_hexdump(*buf, len);
1650 #endif
1651
1652         /* let the rx protocol state machine have as much as it needs */
1653
1654         while (len) {
1655                 /*
1656                  * we were accepting input but now we stopped doing so
1657                  */
1658                 if (!(wsi->rxflow_change_to & LWS_RXFLOW_ALLOW)) {
1659                         lws_rxflow_cache(wsi, *buf, 0, len);
1660                         lwsl_parser("%s: cached %d\n", __func__, len);
1661                         return 1;
1662                 }
1663
1664                 if (wsi->u.ws.rx_draining_ext) {
1665                         m = lws_rx_sm(wsi, 0);
1666                         if (m < 0)
1667                                 return -1;
1668                         continue;
1669                 }
1670
1671                 /* account for what we're using in rxflow buffer */
1672                 if (wsi->rxflow_buffer)
1673                         wsi->rxflow_pos++;
1674
1675                 /* consume payload bytes efficiently */
1676                 if (wsi->lws_rx_parse_state ==
1677                     LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED)
1678                         lws_payload_until_length_exhausted(wsi, buf, &len);
1679
1680                 /* process the byte */
1681                 m = lws_rx_sm(wsi, *(*buf)++);
1682                 if (m < 0)
1683                         return -1;
1684                 len--;
1685         }
1686
1687         lwsl_parser("%s: exit with %d unused\n", __func__, (int)len);
1688
1689         return 0;
1690 }
1691
1692 LWS_VISIBLE void
1693 lws_server_get_canonical_hostname(struct lws_context *context,
1694                                   struct lws_context_creation_info *info)
1695 {
1696         if (lws_check_opt(info->options, LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME))
1697                 return;
1698 #if LWS_POSIX
1699         /* find canonical hostname */
1700         gethostname((char *)context->canonical_hostname,
1701                     sizeof(context->canonical_hostname) - 1);
1702
1703         lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
1704 #else
1705         (void)context;
1706 #endif
1707 }