mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
minimal-http-server-libuv-foreign
This commit is contained in:
parent
b9c7f3df92
commit
e052edb14f
8 changed files with 297 additions and 1 deletions
|
@ -4,7 +4,8 @@ minimal-http-server-dynamic|Serves both static and dynamically generated http co
|
|||
minimal-http-server-form-get|Process a GET form
|
||||
minimal-http-server-form-post-file|Process a multipart POST form with file transfer
|
||||
minimal-http-server-form-post|Process a POST form (no file transfer)
|
||||
minimal-http-server-libuv|Same as minimal-http-server but libuv event loop
|
||||
minimal-http-server-libuv-foreign|Same as minimal-http-server but lws uses a foreign libuv event loop
|
||||
minimal-http-server-libuv|Same as minimal-http-server but lws uses its own libuv event loop
|
||||
minimal-http-server-multivhost|Same as minimal-http-server but three different vhosts
|
||||
minimal-http-server-smp|Multiple service threads
|
||||
minimal-http-server-tls|Serves a directory over http/1 or http/2 with TLS (SSL), custom 404 handler
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
set(SAMP lws-minimal-http-server-libuv-foreign)
|
||||
set(SRCS minimal-http-server-libuv-foreign.c)
|
||||
|
||||
# If we are being built as part of lws, confirm current build config supports
|
||||
# reqconfig, else skip building ourselves.
|
||||
#
|
||||
# If we are being built externally, confirm installed lws was configured to
|
||||
# support reqconfig, else error out with a helpful message about the problem.
|
||||
#
|
||||
MACRO(require_lws_config reqconfig _val result)
|
||||
|
||||
if (DEFINED ${reqconfig})
|
||||
if (${reqconfig})
|
||||
set (rq 1)
|
||||
else()
|
||||
set (rq 0)
|
||||
endif()
|
||||
else()
|
||||
set(rq 0)
|
||||
endif()
|
||||
|
||||
if (${_val} EQUAL ${rq})
|
||||
set(SAME 1)
|
||||
else()
|
||||
set(SAME 0)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME})
|
||||
if (${_val})
|
||||
message("${SAMP}: skipping as lws being built without ${reqconfig}")
|
||||
else()
|
||||
message("${SAMP}: skipping as lws built with ${reqconfig}")
|
||||
endif()
|
||||
set(${result} 0)
|
||||
else()
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES)
|
||||
set(MET ${SAME})
|
||||
else()
|
||||
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig})
|
||||
if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig})
|
||||
set(HAS_${reqconfig} 0)
|
||||
else()
|
||||
set(HAS_${reqconfig} 1)
|
||||
endif()
|
||||
if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val}))
|
||||
set(MET 1)
|
||||
else()
|
||||
set(MET 0)
|
||||
endif()
|
||||
endif()
|
||||
if (NOT MET)
|
||||
if (${_val})
|
||||
message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}")
|
||||
else()
|
||||
message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
set(requirements 1)
|
||||
require_lws_config(LWS_WITH_LIBUV 1 requirements)
|
||||
require_lws_config(LWS_WITHOUT_SERVER 0 requirements)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\n#include <uv.h>\nint main(void) {\n#if (UV_VERSION_MAJOR > 0)\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_RECENT_LIBUV)
|
||||
if (NOT HAS_RECENT_LIBUV)
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES)
|
||||
message("libuv is too old (pre- 1.0)")
|
||||
else()
|
||||
message(FATAL_ERROR "libuv is too old (pre- 1.0)")
|
||||
endif()
|
||||
set(requirements 0)
|
||||
endif()
|
||||
|
||||
if (requirements)
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
||||
if (websockets_shared)
|
||||
target_link_libraries(${SAMP} websockets_shared uv)
|
||||
add_dependencies(${SAMP} websockets_shared)
|
||||
else()
|
||||
target_link_libraries(${SAMP} websockets uv)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,31 @@
|
|||
# lws minimal http server libuv foreign
|
||||
|
||||
This demonstrates having lws take part in a libuv loop owned by
|
||||
something else, with its own objects running in the loop.
|
||||
|
||||
Lws can join the loop, and clean up perfectly after itself.
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ ./lws-minimal-http-server-libuv-foreign
|
||||
[2018/03/29 12:19:31:3480] USER: LWS minimal http server libuv + foreign loop | visit http://localhost:7681
|
||||
[2018/03/29 12:19:31:3724] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 off
|
||||
[2018/03/29 12:19:31:3804] NOTICE: Using foreign event loop...
|
||||
[2018/03/29 12:19:31:3938] USER: Foreign 1Hz timer
|
||||
[2018/03/29 12:19:32:4011] USER: Foreign 1Hz timer
|
||||
[2018/03/29 12:19:33:4024] USER: Foreign 1Hz timer
|
||||
^C[2018/03/29 12:19:33:8868] NOTICE: Signal 2 caught, exiting...
|
||||
[2018/03/29 12:19:33:8963] USER: main: starting exit cleanup...
|
||||
[2018/03/29 12:19:33:9064] USER: main: lws context destroyed: cleaning the foreign loop
|
||||
[2018/03/29 12:19:33:9108] USER: main: exiting...
|
||||
```
|
||||
|
||||
Visit http://localhost:7681
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* lws-minimal-http-server-libuv-foreign
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* This demonstrates the most minimal http server you can make with lws that
|
||||
* uses a libuv event loop created outside lws. It shows how lws can
|
||||
* participate in someone else's event loop and clean up after itself.
|
||||
*
|
||||
* To keep it simple, it serves stuff from the subdirectory
|
||||
* "./mount-origin" of the directory it was started in.
|
||||
* You can change that by changing mount.origin below.
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
static struct lws_context *context;
|
||||
|
||||
static const struct lws_http_mount mount = {
|
||||
/* .mount_next */ NULL, /* linked-list "next" */
|
||||
/* .mountpoint */ "/", /* mountpoint URL */
|
||||
/* .origin */ "./mount-origin", /* serve from dir */
|
||||
/* .def */ "index.html", /* default filename */
|
||||
/* .protocol */ NULL,
|
||||
/* .cgienv */ NULL,
|
||||
/* .extra_mimetypes */ NULL,
|
||||
/* .interpret */ NULL,
|
||||
/* .cgi_timeout */ 0,
|
||||
/* .cache_max_age */ 0,
|
||||
/* .auth_mask */ 0,
|
||||
/* .cache_reusable */ 0,
|
||||
/* .cache_revalidate */ 0,
|
||||
/* .cache_intermediaries */ 0,
|
||||
/* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
|
||||
/* .mountpoint_len */ 1, /* char count */
|
||||
/* .basic_auth_login_file */ NULL,
|
||||
};
|
||||
|
||||
void signal_cb(uv_signal_t *watcher, int signum)
|
||||
{
|
||||
lwsl_notice("Signal %d caught, exiting...\n", watcher->signum);
|
||||
|
||||
switch (watcher->signum) {
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
break;
|
||||
default:
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
lws_libuv_stop(context);
|
||||
}
|
||||
|
||||
/* this logs once a second to show that the foreign loop assets are working */
|
||||
|
||||
static void timer_cb(uv_timer_t *t)
|
||||
{
|
||||
lwsl_user("Foreign 1Hz timer\n");
|
||||
}
|
||||
|
||||
static void lws_uv_close_cb(uv_handle_t *handle)
|
||||
{
|
||||
}
|
||||
|
||||
static void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
|
||||
{
|
||||
lwsl_info("%s: closing foreign loop asset: %p (type %d)\n",
|
||||
__func__, handle, handle->type);
|
||||
uv_close(handle, lws_uv_close_cb);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
uv_timer_t timer_outer;
|
||||
uv_loop_t loop;
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
info.error_document_404 = "/404.html";
|
||||
info.options = LWS_SERVER_OPTION_LIBUV;
|
||||
|
||||
lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
|
||||
/* for LLL_ verbosity above NOTICE to be built into lws,
|
||||
* lws must have been configured and built with
|
||||
* -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
|
||||
/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
|
||||
/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
|
||||
/* | LLL_DEBUG */, NULL);
|
||||
|
||||
lwsl_user("LWS minimal http server libuv + foreign loop |"
|
||||
" visit http://localhost:7681\n");
|
||||
|
||||
uv_loop_init(&loop);
|
||||
|
||||
uv_timer_init(&loop, &timer_outer);
|
||||
uv_timer_start(&timer_outer, timer_cb, 0, 1000);
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
lws_uv_sigint_cfg(context, 1, signal_cb);
|
||||
|
||||
if (lws_uv_initloop(context, &loop, 0)) {
|
||||
lwsl_err("lws_uv_initloop failed\n");
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
||||
lws_libuv_run(context, 0);
|
||||
|
||||
bail:
|
||||
lwsl_user("%s: starting exit cleanup...\n", __func__);
|
||||
|
||||
/* cleanup the lws part */
|
||||
|
||||
lws_context_destroy(context);
|
||||
lws_context_destroy2(context);
|
||||
|
||||
/* cleanup the foreign loop part */
|
||||
|
||||
lwsl_user("%s: lws context destroyed: cleaning the foreign loop\n",
|
||||
__func__);
|
||||
|
||||
/*
|
||||
* Instead of walking to close all the foreign assets, it's also
|
||||
* fine to close them individually instead as below
|
||||
*/
|
||||
// uv_timer_stop(&timer_outer);
|
||||
// uv_close((uv_handle_t*)&timer_outer, NULL);
|
||||
|
||||
/* close every foreign loop asset unconditionally */
|
||||
uv_walk(&loop, lws_uv_walk_cb, NULL);
|
||||
|
||||
/* let it run until everything completed close */
|
||||
uv_run(&loop, UV_RUN_DEFAULT);
|
||||
|
||||
/* nothing left in the foreign loop, destroy it */
|
||||
|
||||
uv_loop_close(&loop);
|
||||
|
||||
lwsl_user("%s: exiting...\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<meta charset="UTF-8">
|
||||
<html>
|
||||
<body>
|
||||
<img src="libwebsockets.org-logo.png"><br>
|
||||
<h1>404</h1>
|
||||
Sorry, that file doesn't exist.
|
||||
</body>
|
||||
</html>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,13 @@
|
|||
<meta charset="UTF-8">
|
||||
<html>
|
||||
<body>
|
||||
<img src="libwebsockets.org-logo.png"><br>
|
||||
|
||||
Hello from the <b>minimal http server libuv foreign loop example</b>.
|
||||
<br>
|
||||
The timer messages in the console are coming from<br>
|
||||
a timer on the libuv loop set up before the lws context<br>
|
||||
started using it.
|
||||
</body>
|
||||
</html>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Loading…
Add table
Reference in a new issue