1/*
2 * lws-minimal-http-server-tls-80
3 *
4 * Written in 2010-2019 by Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 *
9 * This demonstrates the most minimal http server you can make with lws,
10 * with three extra lines giving it tls (ssl) capabilities, which in
11 * turn allow operation with HTTP/2 if lws was configured for it.
12 *
13 * In addition, it runs a vhost on port 80 with the job of redirecting
14 * and upgrading http clients that came in on port 80 to https on port 443.
15 *
16 * To keep it simple, it serves stuff from the subdirectory
17 * "./mount-origin" of the directory it was started in.
18 *
19 * You can change that by changing mount.origin below.
20 */
21
22#include <libwebsockets.h>
23#include <string.h>
24#include <signal.h>
25
26static int interrupted;
27
28static const struct lws_http_mount mount80 = {
29	/* .mount_next */		NULL,		/* linked-list "next" */
30	/* .mountpoint */		"/",		/* mountpoint URL */
31	/* .origin */			"localhost/",
32	/* .def */			"/",	/* default filename */
33	/* .protocol */			NULL,
34	/* .cgienv */			NULL,
35	/* .extra_mimetypes */		NULL,
36	/* .interpret */		NULL,
37	/* .cgi_timeout */		0,
38	/* .cache_max_age */		0,
39	/* .auth_mask */		0,
40	/* .cache_reusable */		0,
41	/* .cache_revalidate */		0,
42	/* .cache_intermediaries */	0,
43	/* .origin_protocol */		LWSMPRO_REDIR_HTTPS, /* https redir */
44	/* .mountpoint_len */		1,		/* char count */
45	/* .basic_auth_login_file */	NULL,
46};
47
48static const struct lws_http_mount mount = {
49	/* .mount_next */		NULL,		/* linked-list "next" */
50	/* .mountpoint */		"/",		/* mountpoint URL */
51	/* .origin */			"./mount-origin", /* serve from dir */
52	/* .def */			"index.html",	/* default filename */
53	/* .protocol */			NULL,
54	/* .cgienv */			NULL,
55	/* .extra_mimetypes */		NULL,
56	/* .interpret */		NULL,
57	/* .cgi_timeout */		0,
58	/* .cache_max_age */		0,
59	/* .auth_mask */		0,
60	/* .cache_reusable */		0,
61	/* .cache_revalidate */		0,
62	/* .cache_intermediaries */	0,
63	/* .origin_protocol */		LWSMPRO_FILE,	/* files in a dir */
64	/* .mountpoint_len */		1,		/* char count */
65	/* .basic_auth_login_file */	NULL,
66};
67
68void sigint_handler(int sig)
69{
70	interrupted = 1;
71}
72
73int main(int argc, const char **argv)
74{
75	struct lws_context_creation_info info;
76	struct lws_context *context;
77	const char *p;
78	int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
79			/* for LLL_ verbosity above NOTICE to be built into lws,
80			 * lws must have been configured and built with
81			 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
82			/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
83			/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
84			/* | LLL_DEBUG */;
85
86	if ((p = lws_cmdline_option(argc, argv, "-d")))
87		logs = atoi(p);
88
89	lws_set_log_level(logs, NULL);
90	lwsl_user("LWS minimal http server TLS + 80 | visit https://localhost\n");
91	lwsl_user(" Run as ROOT so can listen on 443\n");
92
93	signal(SIGINT, sigint_handler);
94
95	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
96
97	info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
98		       LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
99		LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
100
101	context = lws_create_context(&info);
102	if (!context) {
103		lwsl_err("lws init failed\n");
104		return 1;
105	}
106
107
108	info.port = 80;
109	info.mounts = &mount80;
110	info.vhost_name = "localhost80";
111
112	if (!lws_create_vhost(context, &info)) {
113		lwsl_err("Failed to create tls vhost\n");
114		goto bail;
115	}
116
117	info.port = 443;
118	info.mounts = &mount;
119	info.error_document_404 = "/404.html";
120	info.ssl_cert_filepath = "localhost-100y.cert";
121	info.ssl_private_key_filepath = "localhost-100y.key";
122	info.vhost_name = "localhost";
123
124	if (!lws_create_vhost(context, &info)) {
125		lwsl_err("Failed to create tls vhost\n");
126		goto bail;
127	}
128
129	while (n >= 0 && !interrupted)
130		n = lws_service(context, 0);
131
132bail:
133	lws_context_destroy(context);
134
135	return 0;
136}
137