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