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