1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-minimal-http-server-deaddrop
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2010-2020 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  *
9*1c60b9acSAndroid Build Coastguard Worker  * This demonstrates how you can leverage the lws deaddrop plugin to make a
10*1c60b9acSAndroid Build Coastguard Worker  * secure, modern html5 file upload and sharing application.
11*1c60b9acSAndroid Build Coastguard Worker  *
12*1c60b9acSAndroid Build Coastguard Worker  * Because the guts are in a plugin, you can avoid all this setup by using the
13*1c60b9acSAndroid Build Coastguard Worker  * plugin from lwsws and do the config in JSON.
14*1c60b9acSAndroid Build Coastguard Worker  */
15*1c60b9acSAndroid Build Coastguard Worker 
16*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
17*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
18*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
19*1c60b9acSAndroid Build Coastguard Worker #include <time.h>
20*1c60b9acSAndroid Build Coastguard Worker 
21*1c60b9acSAndroid Build Coastguard Worker #define LWS_PLUGIN_STATIC
22*1c60b9acSAndroid Build Coastguard Worker #include "../plugins/deaddrop/protocol_lws_deaddrop.c"
23*1c60b9acSAndroid Build Coastguard Worker 
24*1c60b9acSAndroid Build Coastguard Worker static struct lws_protocols protocols[] = {
25*1c60b9acSAndroid Build Coastguard Worker        LWS_PLUGIN_PROTOCOL_DEADDROP,
26*1c60b9acSAndroid Build Coastguard Worker        LWS_PROTOCOL_LIST_TERM
27*1c60b9acSAndroid Build Coastguard Worker };
28*1c60b9acSAndroid Build Coastguard Worker 
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker static int interrupted;
31*1c60b9acSAndroid Build Coastguard Worker 
32*1c60b9acSAndroid Build Coastguard Worker /*
33*1c60b9acSAndroid Build Coastguard Worker  * teach the /get mount how to present various filetypes to the client...
34*1c60b9acSAndroid Build Coastguard Worker  * lws won't serve files it doesn't know the mimetype for as a security
35*1c60b9acSAndroid Build Coastguard Worker  * measure.
36*1c60b9acSAndroid Build Coastguard Worker  */
37*1c60b9acSAndroid Build Coastguard Worker 
38*1c60b9acSAndroid Build Coastguard Worker static struct lws_protocol_vhost_options em3 = {
39*1c60b9acSAndroid Build Coastguard Worker         NULL, NULL, ".zip", "application/zip"
40*1c60b9acSAndroid Build Coastguard Worker }, em2 = {
41*1c60b9acSAndroid Build Coastguard Worker 	&em3, NULL, ".pdf", "application/pdf"
42*1c60b9acSAndroid Build Coastguard Worker }, extra_mimetypes = {
43*1c60b9acSAndroid Build Coastguard Worker 	&em2, NULL, ".tar.gz", "application/x-gzip"
44*1c60b9acSAndroid Build Coastguard Worker };
45*1c60b9acSAndroid Build Coastguard Worker 
46*1c60b9acSAndroid Build Coastguard Worker /* wire up /upload URLs to the plugin (protected by basic auth) */
47*1c60b9acSAndroid Build Coastguard Worker 
48*1c60b9acSAndroid Build Coastguard Worker static const struct lws_http_mount mount_upload = {
49*1c60b9acSAndroid Build Coastguard Worker 	/* .mount_next */		NULL,
50*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint */		"/upload",	/* mountpoint URL */
51*1c60b9acSAndroid Build Coastguard Worker 	/* .origin */			"lws-deaddrop",
52*1c60b9acSAndroid Build Coastguard Worker 	/* .def */			"",
53*1c60b9acSAndroid Build Coastguard Worker 	/* .protocol */			NULL,
54*1c60b9acSAndroid Build Coastguard Worker 	/* .cgienv */			NULL,
55*1c60b9acSAndroid Build Coastguard Worker 	/* .extra_mimetypes */		NULL,
56*1c60b9acSAndroid Build Coastguard Worker 	/* .interpret */		NULL,
57*1c60b9acSAndroid Build Coastguard Worker 	/* .cgi_timeout */		0,
58*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_max_age */		0,
59*1c60b9acSAndroid Build Coastguard Worker 	/* .auth_mask */		0,
60*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_reusable */		0,
61*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_revalidate */		0,
62*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_intermediaries */	0,
63*1c60b9acSAndroid Build Coastguard Worker 	/* .origin_protocol */		LWSMPRO_CALLBACK,
64*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint_len */		7,		/* char count */
65*1c60b9acSAndroid Build Coastguard Worker 	/* .basic_auth_login_file */	"./ba-passwords",
66*1c60b9acSAndroid Build Coastguard Worker };
67*1c60b9acSAndroid Build Coastguard Worker 
68*1c60b9acSAndroid Build Coastguard Worker /* wire up /get URLs to the upload directory (protected by basic auth) */
69*1c60b9acSAndroid Build Coastguard Worker 
70*1c60b9acSAndroid Build Coastguard Worker static const struct lws_http_mount mount_get = {
71*1c60b9acSAndroid Build Coastguard Worker 	/* .mount_next */		&mount_upload,	/* linked-list "next" */
72*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint */		"/get",	/* mountpoint URL */
73*1c60b9acSAndroid Build Coastguard Worker 	/* .origin */			"./uploads",
74*1c60b9acSAndroid Build Coastguard Worker 	/* .def */			"",
75*1c60b9acSAndroid Build Coastguard Worker 	/* .protocol */			NULL,
76*1c60b9acSAndroid Build Coastguard Worker 	/* .cgienv */			NULL,
77*1c60b9acSAndroid Build Coastguard Worker 	/* .extra_mimetypes */		&extra_mimetypes,
78*1c60b9acSAndroid Build Coastguard Worker 	/* .interpret */		NULL,
79*1c60b9acSAndroid Build Coastguard Worker 	/* .cgi_timeout */		0,
80*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_max_age */		0,
81*1c60b9acSAndroid Build Coastguard Worker 	/* .auth_mask */		0,
82*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_reusable */		0,
83*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_revalidate */		0,
84*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_intermediaries */	0,
85*1c60b9acSAndroid Build Coastguard Worker 	/* .origin_protocol */		LWSMPRO_FILE, /* dynamic */
86*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint_len */		4,		/* char count */
87*1c60b9acSAndroid Build Coastguard Worker 	/* .basic_auth_login_file */	"./ba-passwords",
88*1c60b9acSAndroid Build Coastguard Worker };
89*1c60b9acSAndroid Build Coastguard Worker 
90*1c60b9acSAndroid Build Coastguard Worker /* wire up / to serve from ./mount-origin (protected by basic auth) */
91*1c60b9acSAndroid Build Coastguard Worker 
92*1c60b9acSAndroid Build Coastguard Worker static const struct lws_http_mount mount = {
93*1c60b9acSAndroid Build Coastguard Worker 	/* .mount_next */		&mount_get,	/* linked-list "next" */
94*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint */		"/",		/* mountpoint URL */
95*1c60b9acSAndroid Build Coastguard Worker 	/* .origin */			"./mount-origin", /* serve from dir */
96*1c60b9acSAndroid Build Coastguard Worker 	/* .def */			"index.html",	/* default filename */
97*1c60b9acSAndroid Build Coastguard Worker 	/* .protocol */			NULL,
98*1c60b9acSAndroid Build Coastguard Worker 	/* .cgienv */			NULL,
99*1c60b9acSAndroid Build Coastguard Worker 	/* .extra_mimetypes */		NULL,
100*1c60b9acSAndroid Build Coastguard Worker 	/* .interpret */		NULL,
101*1c60b9acSAndroid Build Coastguard Worker 	/* .cgi_timeout */		0,
102*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_max_age */		0,
103*1c60b9acSAndroid Build Coastguard Worker 	/* .auth_mask */		0,
104*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_reusable */		0,
105*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_revalidate */		0,
106*1c60b9acSAndroid Build Coastguard Worker 	/* .cache_intermediaries */	0,
107*1c60b9acSAndroid Build Coastguard Worker 	/* .origin_protocol */		LWSMPRO_FILE,	/* files in a dir */
108*1c60b9acSAndroid Build Coastguard Worker 	/* .mountpoint_len */		1,		/* char count */
109*1c60b9acSAndroid Build Coastguard Worker 	/* .basic_auth_login_file */	"./ba-passwords",
110*1c60b9acSAndroid Build Coastguard Worker };
111*1c60b9acSAndroid Build Coastguard Worker 
112*1c60b9acSAndroid Build Coastguard Worker /* pass config options to the deaddrop plugin using pvos */
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker static struct lws_protocol_vhost_options pvo3 = {
115*1c60b9acSAndroid Build Coastguard Worker 	/* make the wss also require to pass basic auth */
116*1c60b9acSAndroid Build Coastguard Worker 	NULL, NULL, "basic-auth", "./ba-passwords"
117*1c60b9acSAndroid Build Coastguard Worker }, pvo2 = {
118*1c60b9acSAndroid Build Coastguard Worker 	&pvo3, NULL, "max-size", "10000000"
119*1c60b9acSAndroid Build Coastguard Worker }, pvo1 = {
120*1c60b9acSAndroid Build Coastguard Worker         &pvo2, NULL, "upload-dir", "./uploads" /* would be an absolute path */
121*1c60b9acSAndroid Build Coastguard Worker }, pvo = {
122*1c60b9acSAndroid Build Coastguard Worker         NULL,                  /* "next" pvo linked-list */
123*1c60b9acSAndroid Build Coastguard Worker         &pvo1,                 /* "child" pvo linked-list */
124*1c60b9acSAndroid Build Coastguard Worker         "lws-deaddrop",        /* protocol name we belong to on this vhost */
125*1c60b9acSAndroid Build Coastguard Worker         ""                     /* ignored */
126*1c60b9acSAndroid Build Coastguard Worker };
127*1c60b9acSAndroid Build Coastguard Worker 
sigint_handler(int sig)128*1c60b9acSAndroid Build Coastguard Worker void sigint_handler(int sig)
129*1c60b9acSAndroid Build Coastguard Worker {
130*1c60b9acSAndroid Build Coastguard Worker 	interrupted = 1;
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)133*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
134*1c60b9acSAndroid Build Coastguard Worker {
135*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_creation_info info;
136*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context;
137*1c60b9acSAndroid Build Coastguard Worker 	const char *p;
138*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
139*1c60b9acSAndroid Build Coastguard Worker 
140*1c60b9acSAndroid Build Coastguard Worker 	signal(SIGINT, sigint_handler);
141*1c60b9acSAndroid Build Coastguard Worker 
142*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-d")))
143*1c60b9acSAndroid Build Coastguard Worker 		logs = atoi(p);
144*1c60b9acSAndroid Build Coastguard Worker 
145*1c60b9acSAndroid Build Coastguard Worker 	lws_set_log_level(logs, NULL);
146*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS minimal http server deaddrop | visit https://localhost:7681\n");
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker 	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
149*1c60b9acSAndroid Build Coastguard Worker 	info.port = 7681;
150*1c60b9acSAndroid Build Coastguard Worker 	info.mounts = &mount;
151*1c60b9acSAndroid Build Coastguard Worker 	info.pvo = &pvo;
152*1c60b9acSAndroid Build Coastguard Worker 	info.protocols = protocols;
153*1c60b9acSAndroid Build Coastguard Worker 	info.error_document_404 = "/404.html";
154*1c60b9acSAndroid Build Coastguard Worker 	info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
155*1c60b9acSAndroid Build Coastguard Worker 		LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
156*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_TLS)
157*1c60b9acSAndroid Build Coastguard Worker 	info.ssl_cert_filepath = "localhost-100y.cert";
158*1c60b9acSAndroid Build Coastguard Worker 	info.ssl_private_key_filepath = "localhost-100y.key";
159*1c60b9acSAndroid Build Coastguard Worker #endif
160*1c60b9acSAndroid Build Coastguard Worker 
161*1c60b9acSAndroid Build Coastguard Worker 	context = lws_create_context(&info);
162*1c60b9acSAndroid Build Coastguard Worker 	if (!context) {
163*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws init failed\n");
164*1c60b9acSAndroid Build Coastguard Worker 		return 1;
165*1c60b9acSAndroid Build Coastguard Worker 	}
166*1c60b9acSAndroid Build Coastguard Worker 
167*1c60b9acSAndroid Build Coastguard Worker 	while (n >= 0 && !interrupted)
168*1c60b9acSAndroid Build Coastguard Worker 		n = lws_service(context, 0);
169*1c60b9acSAndroid Build Coastguard Worker 
170*1c60b9acSAndroid Build Coastguard Worker 	lws_context_destroy(context);
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker 	return 0;
173*1c60b9acSAndroid Build Coastguard Worker }
174