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