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