1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * lws-minimal-http-server-multivhost
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Written in 2010-2019 by Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0
7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication.
8d4afb5ceSopenharmony_ci *
9d4afb5ceSopenharmony_ci * This demonstrates the most minimal http server you can make with lws.
10d4afb5ceSopenharmony_ci *
11d4afb5ceSopenharmony_ci * To keep it simple, it serves stuff from the subdirectory
12d4afb5ceSopenharmony_ci * "./mount-origin" of the directory it was started in.
13d4afb5ceSopenharmony_ci * You can change that by changing mount.origin below.
14d4afb5ceSopenharmony_ci */
15d4afb5ceSopenharmony_ci
16d4afb5ceSopenharmony_ci#include <libwebsockets.h>
17d4afb5ceSopenharmony_ci#include <string.h>
18d4afb5ceSopenharmony_ci#include <signal.h>
19d4afb5ceSopenharmony_ci
20d4afb5ceSopenharmony_cistatic int interrupted;
21d4afb5ceSopenharmony_ci
22d4afb5ceSopenharmony_cistatic const struct lws_http_mount mount_localhost1 = {
23d4afb5ceSopenharmony_ci	/* .mount_next */		NULL,		/* linked-list "next" */
24d4afb5ceSopenharmony_ci	/* .mountpoint */		"/",		/* mountpoint URL */
25d4afb5ceSopenharmony_ci	/* .origin */			"./mount-origin-localhost1",
26d4afb5ceSopenharmony_ci	/* .def */			"index.html",	/* default filename */
27d4afb5ceSopenharmony_ci	/* .protocol */			NULL,
28d4afb5ceSopenharmony_ci	/* .cgienv */			NULL,
29d4afb5ceSopenharmony_ci	/* .extra_mimetypes */		NULL,
30d4afb5ceSopenharmony_ci	/* .interpret */		NULL,
31d4afb5ceSopenharmony_ci	/* .cgi_timeout */		0,
32d4afb5ceSopenharmony_ci	/* .cache_max_age */		0,
33d4afb5ceSopenharmony_ci	/* .auth_mask */		0,
34d4afb5ceSopenharmony_ci	/* .cache_reusable */		0,
35d4afb5ceSopenharmony_ci	/* .cache_revalidate */		0,
36d4afb5ceSopenharmony_ci	/* .cache_intermediaries */	0,
37d4afb5ceSopenharmony_ci	/* .origin_protocol */		LWSMPRO_FILE,	/* files in a dir */
38d4afb5ceSopenharmony_ci	/* .mountpoint_len */		1,		/* char count */
39d4afb5ceSopenharmony_ci	/* .basic_auth_login_file */	NULL,
40d4afb5ceSopenharmony_ci}, mount_localhost2 = {
41d4afb5ceSopenharmony_ci	/* .mount_next */		NULL,		/* linked-list "next" */
42d4afb5ceSopenharmony_ci	/* .mountpoint */		"/",		/* mountpoint URL */
43d4afb5ceSopenharmony_ci	/* .origin */			"./mount-origin-localhost2",
44d4afb5ceSopenharmony_ci	/* .def */			"index.html",	/* default filename */
45d4afb5ceSopenharmony_ci	/* .protocol */			NULL,
46d4afb5ceSopenharmony_ci	/* .cgienv */			NULL,
47d4afb5ceSopenharmony_ci	/* .extra_mimetypes */		NULL,
48d4afb5ceSopenharmony_ci	/* .interpret */		NULL,
49d4afb5ceSopenharmony_ci	/* .cgi_timeout */		0,
50d4afb5ceSopenharmony_ci	/* .cache_max_age */		0,
51d4afb5ceSopenharmony_ci	/* .auth_mask */		0,
52d4afb5ceSopenharmony_ci	/* .cache_reusable */		0,
53d4afb5ceSopenharmony_ci	/* .cache_revalidate */		0,
54d4afb5ceSopenharmony_ci	/* .cache_intermediaries */	0,
55d4afb5ceSopenharmony_ci	/* .origin_protocol */		LWSMPRO_FILE,	/* files in a dir */
56d4afb5ceSopenharmony_ci	/* .mountpoint_len */		1,		/* char count */
57d4afb5ceSopenharmony_ci	/* .basic_auth_login_file */	NULL,
58d4afb5ceSopenharmony_ci}, mount_localhost3 = {
59d4afb5ceSopenharmony_ci	/* .mount_next */		NULL,		/* linked-list "next" */
60d4afb5ceSopenharmony_ci	/* .mountpoint */		"/",		/* mountpoint URL */
61d4afb5ceSopenharmony_ci	/* .origin */			"./mount-origin-localhost3",
62d4afb5ceSopenharmony_ci	/* .def */			"index.html",	/* default filename */
63d4afb5ceSopenharmony_ci	/* .protocol */			NULL,
64d4afb5ceSopenharmony_ci	/* .cgienv */			NULL,
65d4afb5ceSopenharmony_ci	/* .extra_mimetypes */		NULL,
66d4afb5ceSopenharmony_ci	/* .interpret */		NULL,
67d4afb5ceSopenharmony_ci	/* .cgi_timeout */		0,
68d4afb5ceSopenharmony_ci	/* .cache_max_age */		0,
69d4afb5ceSopenharmony_ci	/* .auth_mask */		0,
70d4afb5ceSopenharmony_ci	/* .cache_reusable */		0,
71d4afb5ceSopenharmony_ci	/* .cache_revalidate */		0,
72d4afb5ceSopenharmony_ci	/* .cache_intermediaries */	0,
73d4afb5ceSopenharmony_ci	/* .origin_protocol */		LWSMPRO_FILE,	/* files in a dir */
74d4afb5ceSopenharmony_ci	/* .mountpoint_len */		1,		/* char count */
75d4afb5ceSopenharmony_ci	/* .basic_auth_login_file */	NULL,
76d4afb5ceSopenharmony_ci};
77d4afb5ceSopenharmony_ci
78d4afb5ceSopenharmony_civoid sigint_handler(int sig)
79d4afb5ceSopenharmony_ci{
80d4afb5ceSopenharmony_ci	interrupted = 1;
81d4afb5ceSopenharmony_ci}
82d4afb5ceSopenharmony_ci
83d4afb5ceSopenharmony_civoid vh_destruction_notification(struct lws_vhost *vh, void *arg)
84d4afb5ceSopenharmony_ci{
85d4afb5ceSopenharmony_ci	lwsl_user("%s: called, arg: %p\n", __func__, arg);
86d4afb5ceSopenharmony_ci}
87d4afb5ceSopenharmony_ci
88d4afb5ceSopenharmony_ciint main(int argc, const char **argv)
89d4afb5ceSopenharmony_ci{
90d4afb5ceSopenharmony_ci	struct lws_context_creation_info info;
91d4afb5ceSopenharmony_ci	struct lws_context *context;
92d4afb5ceSopenharmony_ci	struct lws_vhost *new_vhost;
93d4afb5ceSopenharmony_ci	const char *p;
94d4afb5ceSopenharmony_ci	int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
95d4afb5ceSopenharmony_ci			/* for LLL_ verbosity above NOTICE to be built into lws,
96d4afb5ceSopenharmony_ci			 * lws must have been configured and built with
97d4afb5ceSopenharmony_ci			 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
98d4afb5ceSopenharmony_ci			/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
99d4afb5ceSopenharmony_ci			/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
100d4afb5ceSopenharmony_ci			/* | LLL_DEBUG */;
101d4afb5ceSopenharmony_ci
102d4afb5ceSopenharmony_ci	if ((p = lws_cmdline_option(argc, argv, "-d")))
103d4afb5ceSopenharmony_ci		logs = atoi(p);
104d4afb5ceSopenharmony_ci
105d4afb5ceSopenharmony_ci	lws_set_log_level(logs, NULL);
106d4afb5ceSopenharmony_ci	lwsl_user("LWS minimal http server-multivhost | visit http://localhost:7681 / 7682\n");
107d4afb5ceSopenharmony_ci
108d4afb5ceSopenharmony_ci	signal(SIGINT, sigint_handler);
109d4afb5ceSopenharmony_ci
110d4afb5ceSopenharmony_ci	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
111d4afb5ceSopenharmony_ci	info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
112d4afb5ceSopenharmony_ci		LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
113d4afb5ceSopenharmony_ci
114d4afb5ceSopenharmony_ci	/*
115d4afb5ceSopenharmony_ci	 * Because of LWS_SERVER_OPTION_EXPLICIT_VHOSTS, this only creates
116d4afb5ceSopenharmony_ci	 * the context and no longer creates a default vhost
117d4afb5ceSopenharmony_ci	 */
118d4afb5ceSopenharmony_ci	context = lws_create_context(&info);
119d4afb5ceSopenharmony_ci	if (!context) {
120d4afb5ceSopenharmony_ci		lwsl_err("lws init failed\n");
121d4afb5ceSopenharmony_ci		return 1;
122d4afb5ceSopenharmony_ci	}
123d4afb5ceSopenharmony_ci
124d4afb5ceSopenharmony_ci	/* it's our job now to create the vhosts we want:
125d4afb5ceSopenharmony_ci	 *
126d4afb5ceSopenharmony_ci	 *   - "localhost1" listen on 7681 and serve ./mount-origin-localhost1/
127d4afb5ceSopenharmony_ci	 *   - "localhost2" listen on 7682 and serve ./mount-origin-localhost2/
128d4afb5ceSopenharmony_ci	 *   - "localhost3" share 7682 and serve ./mount-origin-localhost3/
129d4afb5ceSopenharmony_ci	 *
130d4afb5ceSopenharmony_ci	 * Note lws supports dynamic vhost creation and destruction at runtime.
131d4afb5ceSopenharmony_ci	 * When using multi-vhost with your own protocols, you must provide a
132d4afb5ceSopenharmony_ci	 * pvo for each vhost naming each protocol you want enabled on it.
133d4afb5ceSopenharmony_ci	 * minimal-ws-server-threads demonstrates how to provide pvos.
134d4afb5ceSopenharmony_ci	 */
135d4afb5ceSopenharmony_ci
136d4afb5ceSopenharmony_ci	info.port = 7681;
137d4afb5ceSopenharmony_ci	info.mounts = &mount_localhost1;
138d4afb5ceSopenharmony_ci	info.error_document_404 = "/404.html";
139d4afb5ceSopenharmony_ci	info.vhost_name = "localhost1";
140d4afb5ceSopenharmony_ci
141d4afb5ceSopenharmony_ci	if (!lws_create_vhost(context, &info)) {
142d4afb5ceSopenharmony_ci		lwsl_err("Failed to create first vhost\n");
143d4afb5ceSopenharmony_ci		goto bail;
144d4afb5ceSopenharmony_ci	}
145d4afb5ceSopenharmony_ci
146d4afb5ceSopenharmony_ci	info.port = 7682;
147d4afb5ceSopenharmony_ci	info.mounts = &mount_localhost2;
148d4afb5ceSopenharmony_ci	info.error_document_404 = "/404.html";
149d4afb5ceSopenharmony_ci	info.vhost_name = "localhost2";
150d4afb5ceSopenharmony_ci
151d4afb5ceSopenharmony_ci	if (!lws_cmdline_option(argc, argv, "--kill-7682")) {
152d4afb5ceSopenharmony_ci
153d4afb5ceSopenharmony_ci		if (!lws_create_vhost(context, &info)) {
154d4afb5ceSopenharmony_ci			lwsl_err("Failed to create second vhost\n");
155d4afb5ceSopenharmony_ci			goto bail;
156d4afb5ceSopenharmony_ci		}
157d4afb5ceSopenharmony_ci	}
158d4afb5ceSopenharmony_ci
159d4afb5ceSopenharmony_ci	/* a second vhost listens on port 7682 */
160d4afb5ceSopenharmony_ci	info.mounts = &mount_localhost3;
161d4afb5ceSopenharmony_ci	info.error_document_404 = "/404.html";
162d4afb5ceSopenharmony_ci	info.vhost_name = "localhost3";
163d4afb5ceSopenharmony_ci	info.finalize = vh_destruction_notification;
164d4afb5ceSopenharmony_ci	info.finalize_arg = NULL;
165d4afb5ceSopenharmony_ci
166d4afb5ceSopenharmony_ci	new_vhost = lws_create_vhost(context, &info);
167d4afb5ceSopenharmony_ci	if (!new_vhost) {
168d4afb5ceSopenharmony_ci		lwsl_err("Failed to create third vhost\n");
169d4afb5ceSopenharmony_ci		goto bail;
170d4afb5ceSopenharmony_ci	}
171d4afb5ceSopenharmony_ci
172d4afb5ceSopenharmony_ci	if (lws_cmdline_option(argc, argv, "--kill-7682"))
173d4afb5ceSopenharmony_ci		lws_vhost_destroy(new_vhost);
174d4afb5ceSopenharmony_ci
175d4afb5ceSopenharmony_ci	if (lws_cmdline_option(argc, argv, "--die-after-vhost")) {
176d4afb5ceSopenharmony_ci		lwsl_warn("bailing after creating vhosts\n");
177d4afb5ceSopenharmony_ci		goto bail;
178d4afb5ceSopenharmony_ci	}
179d4afb5ceSopenharmony_ci
180d4afb5ceSopenharmony_ci	while (n >= 0 && !interrupted)
181d4afb5ceSopenharmony_ci		n = lws_service(context, 0);
182d4afb5ceSopenharmony_ci
183d4afb5ceSopenharmony_cibail:
184d4afb5ceSopenharmony_ci	lws_context_destroy(context);
185d4afb5ceSopenharmony_ci
186d4afb5ceSopenharmony_ci	return 0;
187d4afb5ceSopenharmony_ci}
188