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