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