1/* 2 * lws-minimal-ws-server 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 a minimal ws server that can cooperate with 10 * other threads cleanly. Two other threads are started, which fill 11 * a ringbuffer with strings at 10Hz. 12 * 13 * The actual work and thread spawning etc are done in the protocol 14 * implementation in protocol_lws_minimal.c. 15 * 16 * To keep it simple, it serves stuff in the subdirectory "./mount-origin" of 17 * the directory it was started in. 18 * You can change that by changing mount.origin. 19 */ 20 21#include <libwebsockets.h> 22#include <string.h> 23#include <signal.h> 24#if defined(WIN32) 25#define HAVE_STRUCT_TIMESPEC 26#if defined(pid_t) 27#undef pid_t 28#endif 29#endif 30#include <pthread.h> 31 32#define LWS_PLUGIN_STATIC 33#include "protocol_lws_minimal.c" 34 35static struct lws_protocols protocols[] = { 36 { "http", lws_callback_http_dummy, 0, 0, 0, NULL, 0 }, 37 LWS_PLUGIN_PROTOCOL_MINIMAL, 38 LWS_PROTOCOL_LIST_TERM 39}; 40 41static int interrupted; 42 43static const struct lws_http_mount mount = { 44 /* .mount_next */ NULL, /* linked-list "next" */ 45 /* .mountpoint */ "/", /* mountpoint URL */ 46 /* .origin */ "./mount-origin", /* serve from dir */ 47 /* .def */ "index.html", /* default filename */ 48 /* .protocol */ NULL, 49 /* .cgienv */ NULL, 50 /* .extra_mimetypes */ NULL, 51 /* .interpret */ NULL, 52 /* .cgi_timeout */ 0, 53 /* .cache_max_age */ 0, 54 /* .auth_mask */ 0, 55 /* .cache_reusable */ 0, 56 /* .cache_revalidate */ 0, 57 /* .cache_intermediaries */ 0, 58 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ 59 /* .mountpoint_len */ 1, /* char count */ 60 /* .basic_auth_login_file */ NULL, 61}; 62 63/* 64 * This demonstrates how to pass a pointer into a specific protocol handler 65 * running on a specific vhost. In this case, it's our default vhost and 66 * we pass the pvo named "config" with the value a const char * "myconfig". 67 * 68 * This is the preferred way to pass configuration into a specific vhost + 69 * protocol instance. 70 */ 71 72static const struct lws_protocol_vhost_options pvo_ops = { 73 NULL, 74 NULL, 75 "config", /* pvo name */ 76 (void *)"myconfig" /* pvo value */ 77}; 78 79static const struct lws_protocol_vhost_options pvo = { 80 NULL, /* "next" pvo linked-list */ 81 &pvo_ops, /* "child" pvo linked-list */ 82 "lws-minimal", /* protocol name we belong to on this vhost */ 83 "" /* ignored */ 84}; 85 86void sigint_handler(int sig) 87{ 88 interrupted = 1; 89} 90 91int main(int argc, const char **argv) 92{ 93 struct lws_context_creation_info info; 94 struct lws_context *context; 95 const char *p; 96 int logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE 97 /* for LLL_ verbosity above NOTICE to be built into lws, 98 * lws must have been configured and built with 99 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ 100 /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ 101 /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ 102 /* | LLL_DEBUG */; 103 104 signal(SIGINT, sigint_handler); 105 106 if ((p = lws_cmdline_option(argc, argv, "-d"))) 107 logs = atoi(p); 108 109 lws_set_log_level(logs, NULL); 110 lwsl_user("LWS minimal ws server + threads | visit http://localhost:7681\n"); 111 112 memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ 113 info.port = 7681; 114 info.mounts = &mount; 115 info.protocols = protocols; 116 info.pvo = &pvo; /* per-vhost options */ 117 info.options = 118 LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; 119 120 context = lws_create_context(&info); 121 if (!context) { 122 lwsl_err("lws init failed\n"); 123 return 1; 124 } 125 126 /* start the threads that create content */ 127 128 while (!interrupted) 129 if (lws_service(context, 0)) 130 interrupted = 1; 131 132 lws_context_destroy(context); 133 134 return 0; 135} 136