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