1/* 2 * lws-minimal-http-server-tls 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 * To keep it simple, it serves stuff from the subdirectory 14 * "./mount-origin" of the directory it was started in. 15 * 16 * You can change that by changing mount.origin below. 17 */ 18 19#include <libwebsockets.h> 20#include <string.h> 21#include <signal.h> 22#include <errno.h> 23 24static int interrupted; 25 26#if defined(LWS_WITH_PLUGINS) 27static const char * const plugin_dirs[] = { 28 LWS_INSTALL_DATADIR"/libwebsockets-test-server/plugins/", 29 NULL 30}; 31#endif 32 33static const struct lws_http_mount 34#if defined(LWS_WITH_SYS_METRICS) 35 mount_metrics = { 36 /* .mount_next */ NULL, /* linked-list "next" */ 37 /* .mountpoint */ "/metrics", /* mountpoint URL */ 38 /* .origin */ "lws-openmetrics", /* serve from dir */ 39 /* .def */ "x", /* default filename */ 40 /* .protocol */ "lws-openmetrics", 41 /* .cgienv */ NULL, 42 /* .extra_mimetypes */ NULL, 43 /* .interpret */ NULL, 44 /* .cgi_timeout */ 0, 45 /* .cache_max_age */ 0, 46 /* .auth_mask */ 0, 47 /* .cache_reusable */ 0, 48 /* .cache_revalidate */ 0, 49 /* .cache_intermediaries */ 0, 50 /* .origin_protocol */ LWSMPRO_CALLBACK, /* bind to callback */ 51 /* .mountpoint_len */ 8, /* char count */ 52 /* .basic_auth_login_file */ NULL, 53 }, 54#endif 55 mount = { 56#if defined(LWS_WITH_SYS_METRICS) 57 /* .mount_next */ &mount_metrics, /* linked-list "next" */ 58#else 59 /* .mount_next */ NULL, /* linked-list "next" */ 60#endif 61 /* .mountpoint */ "/", /* mountpoint URL */ 62 /* .origin */ "./mount-origin", /* serve from dir */ 63 /* .def */ "index.html", /* default filename */ 64 /* .protocol */ "http-only", 65 /* .cgienv */ NULL, 66 /* .extra_mimetypes */ NULL, 67 /* .interpret */ NULL, 68 /* .cgi_timeout */ 0, 69 /* .cache_max_age */ 0, 70 /* .auth_mask */ 0, 71 /* .cache_reusable */ 0, 72 /* .cache_revalidate */ 0, 73 /* .cache_intermediaries */ 0, 74 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ 75 /* .mountpoint_len */ 1, /* char count */ 76 /* .basic_auth_login_file */ NULL, 77}; 78 79#if !defined(WIN32) 80void sigint_handler(int sig, siginfo_t *siginfo, void *context) 81{ 82 pid_t sender_pid = siginfo->si_pid; 83 lwsl_err("%s: sig %d from pid %lu\n", __func__, sig, (unsigned long)sender_pid); 84 interrupted = 1; 85} 86#else 87void sigint_handler(int sig) 88{ 89 interrupted = 1; 90} 91#endif 92 93int main(int argc, const char **argv) 94{ 95 struct lws_context_creation_info info; 96 struct lws_context *context; 97#if !defined(WIN32) 98 struct sigaction siga; 99#endif 100 const char *p; 101 int n = 0; 102 103#if !defined(WIN32) 104 memset(&siga, 0, sizeof(siga)); 105 siga.sa_sigaction = sigint_handler; 106 siga.sa_flags |= SA_SIGINFO; // get detail info 107 108 // change signal action, 109 if (sigaction(SIGINT, &siga, NULL) != 0) { 110 printf("error sigaction()"); 111 return errno; 112 } 113#else 114 signal(SIGINT, sigint_handler); 115#endif 116 memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ 117 lws_cmdline_option_handle_builtin(argc, argv, &info); 118 lwsl_user("LWS minimal http server TLS | visit https://localhost:7681\n"); 119 120 info.port = 7681; 121 if ((p = lws_cmdline_option(argc, argv, "--port"))) 122 info.port = atoi(p); 123 info.mounts = &mount; 124 info.error_document_404 = "/404.html"; 125 info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | 126 LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; 127 info.ssl_cert_filepath = "localhost-100y.cert"; 128 info.ssl_private_key_filepath = "localhost-100y.key"; 129 info.fo_listen_queue = 32; 130 131#if defined(LWS_WITH_PLUGINS) 132 info.plugin_dirs = plugin_dirs; 133#endif 134 135 if (lws_cmdline_option(argc, argv, "-h")) 136 info.options |= LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK; 137 138 context = lws_create_context(&info); 139 if (!context) { 140 lwsl_err("lws init failed\n"); 141 return 1; 142 } 143 144 while (n >= 0 && !interrupted) 145 n = lws_service(context, 0); 146 147 lws_context_destroy(context); 148 149 return 0; 150} 151