{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1711704327,
"reponame":"libwebsockets",
"desc":"libwebsockets lightweight C networking library",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"fe63401361e7aa3c59cecc41d3330804",
"oid":{ "oid": "e4be3317ee421f951fb16a85c7edacc9b8a0e6aa", "alias": [ "refs/heads/main"]},"blobname": "test-apps/test-server.c", "blob": "/*\n * libwebsockets-test-server - libwebsockets test implementation\n *\n * Written in 2010-2019 by Andy Green \u003candy@warmcat.com\u003e\n *\n * This file is made available under the Creative Commons CC0 1.0\n * Universal Public Domain Dedication.\n *\n * The person who associated a work with this deed has dedicated\n * the work to the public domain by waiving all of his or her rights\n * to the work worldwide under copyright law, including all related\n * and neighboring rights, to the extent allowed by law. You can copy,\n * modify, distribute and perform the work, even for commercial purposes,\n * all without asking permission.\n *\n * The test apps are intended to be adapted for use in your code, which\n * may be proprietary.\tSo unlike the library itself, they are licensed\n * Public Domain.\n */\n\n#include \u003clibwebsockets.h\u003e\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\n#include \u003cgetopt.h\u003e\n#endif\n#include \u003csignal.h\u003e\n\n#if defined(WIN32) || defined(_WIN32)\n#else\n#include \u003cunistd.h\u003e\n#endif\n\nint close_testing;\nint max_poll_elements;\nint debug_level \u003d LLL_USER | 7;\n\n#if defined(LWS_WITH_EXTERNAL_POLL)\nstruct lws_pollfd *pollfds;\nint *fd_lookup;\nint count_pollfds;\n#endif\nvolatile int force_exit \u003d 0, dynamic_vhost_enable \u003d 0;\nstruct lws_vhost *dynamic_vhost;\nstruct lws_context *context;\nstruct lws_plat_file_ops fops_plat;\nstatic int test_options;\n\n/* http server gets files from this path */\n#define LOCAL_RESOURCE_PATH INSTALL_DATADIR\u0022/libwebsockets-test-server\u0022\nchar *resource_path \u003d LOCAL_RESOURCE_PATH;\n#if defined(LWS_WITH_TLS) \u0026\u0026 defined(LWS_HAVE_SSL_CTX_set1_param)\nchar crl_path[1024] \u003d \u0022\u0022;\n#endif\n\n/*\n * This demonstrates how to use the clean protocol service separation of\n * plugins, in this case by statically including them at build-time.\n */\n\n#define LWS_PLUGIN_STATIC\n#if defined(LWS_ROLE_WS)\n#include \u0022../plugins/protocol_lws_mirror.c\u0022\n#include \u0022../plugins/protocol_lws_status.c\u0022\n#include \u0022../plugins/protocol_dumb_increment.c\u0022\n#endif\n#include \u0022../plugins/protocol_post_demo.c\u0022\n\n#if defined(LWS_WITH_EXTERNAL_POLL)\nstatic struct lws_pollfd *\next_find_fd(lws_sockfd_type fd)\n{\n\tint n;\n\n\tfor (n \u003d 0; n \u003c max_poll_elements; n++)\n\t\tif (pollfds[n].fd \u003d\u003d fd)\n\t\t\treturn \u0026pollfds[n];\n\n\treturn NULL;\n}\n#endif\n\nstatic int\nlws_callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,\n\t\t void *in, size_t len)\n{\n\tconst unsigned char *c;\n#if defined(LWS_WITH_EXTERNAL_POLL)\n\tstruct lws_pollargs *pa;\n\tstruct lws_pollfd *pfd;\n#endif\n\tchar buf[1024];\n\tint n \u003d 0, hlen;\n\n\tswitch (reason) {\n#if defined(LWS_WITH_EXTERNAL_POLL)\n\tcase LWS_CALLBACK_ADD_POLL_FD:\n\t\tpa \u003d (struct lws_pollargs *)in;\n\t\tlwsl_debug(\u0022%s: ADD fd %d, ev %d\u005cn\u0022, __func__, pa-\u003efd, pa-\u003eevents);\n\t\tpfd \u003d ext_find_fd(pa-\u003efd);\n\t\tif (pfd) {\n\t\t\tlwsl_notice(\u0022%s: ADD fd %d already in ext table\u005cn\u0022,\n\t\t\t\t\t__func__, pa-\u003efd);\n\t\t} else {\n\t\t\tpfd \u003d ext_find_fd(LWS_SOCK_INVALID);\n\t\t\tif (!pfd)\n\t\t\t\treturn -1;\n\t\t}\n\t\tpfd-\u003efd \u003d pa-\u003efd;\n\t\tpfd-\u003eevents \u003d (short)pa-\u003eevents;\n\t\tpfd-\u003erevents \u003d 0;\n\t\t/* high water mark... */\n\t\tcount_pollfds \u003d (int)((pfd - pollfds) + 1);\n\t\tbreak;\n\tcase LWS_CALLBACK_DEL_POLL_FD:\n\t\tpa \u003d (struct lws_pollargs *)in;\n\t\tlwsl_debug(\u0022%s: DEL fd %d\u005cn\u0022, __func__, pa-\u003efd);\n\t\tpfd \u003d ext_find_fd(pa-\u003efd);\n\t\tif (!pfd)\n\t\t\treturn -1;\n\t\tpfd-\u003efd \u003d LWS_SOCK_INVALID;\n\t\tbreak;\n\tcase LWS_CALLBACK_CHANGE_MODE_POLL_FD:\n\t\tpa \u003d (struct lws_pollargs *)in;\n\t\tlwsl_debug(\u0022%s: CH fd %d\u005cn\u0022, __func__, pa-\u003efd);\n\t\tpfd \u003d ext_find_fd(pa-\u003efd);\n\t\tif (!pfd) {\n\t\t\tlwsl_err(\u0022%s: unknown fd %d\u005cn\u0022, __func__, pa-\u003efd);\n\t\t\treturn -1;\n\t\t}\n\t\tpfd-\u003eevents \u003d (short)pa-\u003eevents;\n\t\tbreak;\n#endif\n\tcase LWS_CALLBACK_HTTP:\n\n\t\t/* non-mount-handled accesses will turn up here */\n\n\t\t/* dump the headers */\n\n\t\tdo {\n\t\t\tc \u003d lws_token_to_string((enum lws_token_indexes)n);\n\t\t\tif (!c) {\n\t\t\t\tn++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\thlen \u003d lws_hdr_total_length(wsi, (enum lws_token_indexes)n);\n\t\t\tif (!hlen || hlen \u003e (int)sizeof(buf) - 1) {\n\t\t\t\tn++;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (lws_hdr_copy(wsi, buf, sizeof buf, (enum lws_token_indexes)n) \u003c 0)\n\t\t\t\tfprintf(stderr, \u0022 %s (too big)\u005cn\u0022, (char *)c);\n\t\t\telse {\n\t\t\t\tbuf[sizeof(buf) - 1] \u003d '\u005c0';\n\n\t\t\t\tfprintf(stderr, \u0022 %s \u003d %s\u005cn\u0022, (char *)c, buf);\n\t\t\t}\n\t\t\tn++;\n\t\t} while (c);\n\n\t\t/* dump the individual URI Arg parameters */\n\n\t\tn \u003d 0;\n\t\twhile (lws_hdr_copy_fragment(wsi, buf, sizeof(buf),\n\t\t\t\t\t WSI_TOKEN_HTTP_URI_ARGS, n) \u003e 0) {\n\t\t\tlwsl_notice(\u0022URI Arg %d: %s\u005cn\u0022, ++n, buf);\n\t\t}\n\n\t\tif (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL))\n\t\t\treturn -1;\n\n\t\tif (lws_http_transaction_completed(wsi))\n\t\t\treturn -1;\n\n\t\treturn 0;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn lws_callback_http_dummy(wsi, reason, user, in, len);\n}\n\n/* list of supported protocols and callbacks */\n\nstatic struct lws_protocols protocols[] \u003d {\n\t/* first protocol must always be HTTP handler */\n\n\t{ \u0022http-only\u0022, lws_callback_http, 0, 0, 0, NULL, 0 },\n#if defined(LWS_ROLE_WS)\n\tLWS_PLUGIN_PROTOCOL_DUMB_INCREMENT,\n\tLWS_PLUGIN_PROTOCOL_MIRROR,\n\tLWS_PLUGIN_PROTOCOL_LWS_STATUS,\n#endif\n\tLWS_PLUGIN_PROTOCOL_POST_DEMO,\n\tLWS_PROTOCOL_LIST_TERM\n};\n\n\n/* this shows how to override the lws file operations.\tYou don't need\n * to do any of this unless you have a reason (eg, want to serve\n * compressed files without decompressing the whole archive)\n */\nstatic lws_fop_fd_t\ntest_server_fops_open(const struct lws_plat_file_ops *this_fops,\n\t\t const struct lws_plat_file_ops *fops,\n\t\t const char *vfs_path, const char *vpath,\n\t\t lws_fop_flags_t *flags)\n{\n\tlws_fop_fd_t fop_fd;\n\n\t/* call through to original platform implementation */\n\tfop_fd \u003d fops_plat.open(fops, fops, vfs_path, vpath, flags);\n\n\tif (fop_fd)\n\t\tlwsl_info(\u0022%s: opening %s, ret %p, len %lu\u005cn\u0022, __func__,\n\t\t\t\tvfs_path, fop_fd,\n\t\t\t\t(long)lws_vfs_get_length(fop_fd));\n\telse\n\t\tlwsl_info(\u0022%s: open %s failed\u005cn\u0022, __func__, vfs_path);\n\n\treturn fop_fd;\n}\n\nvoid sighandler(int sig)\n{\n#if !defined(WIN32) \u0026\u0026 !defined(_WIN32)\n\t/* because windows is too dumb to have SIGUSR1... */\n\tif (sig \u003d\u003d SIGUSR1) {\n\t\t/*\n\t\t * For testing, you can fire a SIGUSR1 at the test server\n\t\t * to toggle the existence of an identical server on\n\t\t * port + 1\n\t\t */\n\t\tdynamic_vhost_enable ^\u003d 1;\n\t\tlws_cancel_service(context);\n\t\tlwsl_notice(\u0022SIGUSR1: dynamic_vhost_enable: %d\u005cn\u0022,\n\t\t\t\tdynamic_vhost_enable);\n\t\treturn;\n\t}\n#endif\n\tforce_exit \u003d 1;\n\tlws_cancel_service(context);\n}\n\n#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\nstatic const struct lws_extension exts[] \u003d {\n\t{\n\t\t\u0022permessage-deflate\u0022,\n\t\tlws_extension_callback_pm_deflate,\n\t\t\u0022permessage-deflate\u0022\n\t},\n\t{ NULL, NULL, NULL /* terminator */ }\n};\n#endif\n\n/*\n * mount a filesystem directory into the URL space at /\n * point it to our /usr/share directory with our assets in\n * stuff from here is autoserved by the library\n */\n\nstatic const struct lws_http_mount mount_ziptest_uncomm \u003d {\n\tNULL,\t\t\t/* linked-list pointer to next*/\n\t\u0022/uncommziptest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n\tLOCAL_RESOURCE_PATH\u0022/candide-uncompressed.zip\u0022,\t/* handler */\n\tNULL,\t/* default filename if none given */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\tLWSMPRO_FILE,\t/* origin points to a callback */\n\t14,\t\t\t/* strlen(\u0022/ziptest\u0022), ie length of the mountpoint */\n\tNULL,\n}, mount_ziptest \u003d {\n\t(struct lws_http_mount *)\u0026mount_ziptest_uncomm,\t\t\t/* linked-list pointer to next*/\n\t\u0022/ziptest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n\tLOCAL_RESOURCE_PATH\u0022/candide.zip\u0022,\t/* handler */\n\tNULL,\t/* default filename if none given */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\tLWSMPRO_FILE,\t/* origin points to a callback */\n\t8,\t\t\t/* strlen(\u0022/ziptest\u0022), ie length of the mountpoint */\n\tNULL,\n}, mount_post \u003d {\n\t(struct lws_http_mount *)\u0026mount_ziptest, /* linked-list pointer to next*/\n\t\u0022/formtest\u0022,\t\t/* mountpoint in URL namespace on this vhost */\n\t\u0022protocol-post-demo\u0022,\t/* handler */\n\tNULL,\t/* default filename if none given */\n\tNULL,\n\tNULL,\n\tNULL,\n\tNULL,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\tLWSMPRO_CALLBACK,\t/* origin points to a callback */\n\t9,\t\t\t/* strlen(\u0022/formtest\u0022), ie length of the mountpoint */\n\tNULL,\n}, mount \u003d {\n\t/* .mount_next */\t\t\u0026mount_post,\t/* linked-list \u0022next\u0022 */\n\t/* .mountpoint */\t\t\u0022/\u0022,\t\t/* mountpoint URL */\n\t/* .origin */\t\t\tLOCAL_RESOURCE_PATH, /* serve from dir */\n\t/* .def */\t\t\t\u0022test.html\u0022,\t/* default filename */\n\t/* .protocol */\t\t\tNULL,\n\t/* .cgienv */\t\t\tNULL,\n\t/* .extra_mimetypes */\t\tNULL,\n\t/* .interpret */\t\tNULL,\n\t/* .cgi_timeout */\t\t0,\n\t/* .cache_max_age */\t\t0,\n\t/* .auth_mask */\t\t0,\n\t/* .cache_reusable */\t\t0,\n\t/* .cache_revalidate */\t\t0,\n\t/* .cache_intermediaries */\t0,\n\t/* .cache_no */\t\t\t0,\n\t/* .origin_protocol */\t\tLWSMPRO_FILE,\t/* files in a dir */\n\t/* .mountpoint_len */\t\t1,\t\t/* char count */\n\t/* .basic_auth_login_file */\tNULL,\n};\n\n\nstatic const struct lws_protocol_vhost_options pvo_options \u003d {\n\tNULL,\n\tNULL,\n\t\u0022options\u0022,\t\t/* pvo name */\n\t(void *)\u0026test_options\t/* pvo value */\n};\n\n/*\n * If we don't give any pvos, then for backwards compatibility all protocols\n * are enabled on all vhosts. If we give any pvos, then we must list in them\n * the protocol names we want to enable, protocols that are not listed in the\n * pvos are not instantiated on the vhost then.\n */\n\nstatic const struct lws_protocol_vhost_options\n\tpvo3 \u003d {\n\t\tNULL,\t\t\t\t/* \u0022next\u0022 pvo linked-list */\n\t\tNULL,\n\t\t\u0022protocol-post-demo\u0022,\t/* protocol name we belong to on this vhost */\n\t\t\u0022\u0022\t\t\t\t/* not needed */\n\t},\n\tpvo2 \u003d {\n\t\t\u0026pvo3,\t\t\t\t/* \u0022next\u0022 pvo linked-list */\n\t\tNULL,\n\t\t\u0022lws-status\u0022,\t/* protocol name we belong to on this vhost */\n\t\t\u0022\u0022\t\t\t\t/* not needed */\n\t},\n\tpvo1 \u003d {\n\t\t\u0026pvo2,\t\t\t\t/* \u0022next\u0022 pvo linked-list */\n\t\tNULL,\n\t\t\u0022lws-mirror-protocol\u0022,\t/* protocol name we belong to on this vhost */\n\t\t\u0022\u0022\t\t\t\t/* not needed */\n\t},\n\tpvo \u003d {\n\t\t\u0026pvo1,\t\t\t\t/* \u0022next\u0022 pvo linked-list */\n\t\t\u0026pvo_options,\t\t/* \u0022child\u0022 pvo linked-list */\n\t\t\u0022dumb-increment-protocol\u0022,\t/* protocol name we belong to on this vhost */\n\t\t\u0022\u0022\t\t\t\t/* not needed */\n};\n\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\nstatic struct option options[] \u003d {\n\t{ \u0022help\u0022,\tno_argument,\t\tNULL, 'h' },\n\t{ \u0022debug\u0022,\trequired_argument,\tNULL, 'd' },\n\t{ \u0022port\u0022,\trequired_argument,\tNULL, 'p' },\n\t{ \u0022ssl\u0022,\tno_argument,\t\tNULL, 's' },\n\t{ \u0022allow-non-ssl\u0022,\tno_argument,\tNULL, 'a' },\n\t{ \u0022interface\u0022,\trequired_argument,\tNULL, 'i' },\n\t{ \u0022closetest\u0022,\tno_argument,\t\tNULL, 'c' },\n\t{ \u0022ssl-cert\u0022, required_argument,\tNULL, 'C' },\n\t{ \u0022ssl-key\u0022, required_argument,\tNULL, 'K' },\n\t{ \u0022ssl-ca\u0022, required_argument,\t\tNULL, 'A' },\n\t{ \u0022resource-path\u0022, required_argument,\t\tNULL, 'r' },\n#if defined(LWS_WITH_TLS)\n\t{ \u0022ssl-verify-client\u0022,\tno_argument,\t\tNULL, 'v' },\n#if defined(LWS_HAVE_SSL_CTX_set1_param)\n\t{ \u0022ssl-crl\u0022, required_argument,\t\tNULL, 'R' },\n#endif\n#endif\n\t{ \u0022libev\u0022, no_argument,\t\tNULL, 'e' },\n\t{ \u0022unix-socket\u0022, required_argument,\tNULL, 'U' },\n#ifndef LWS_NO_DAEMONIZE\n\t{ \u0022daemonize\u0022,\tno_argument,\t\tNULL, 'D' },\n#endif\n\t{ \u0022ignore-sigterm\u0022, no_argument,\tNULL, 'I' },\n\n\t{ NULL, 0, 0, 0 }\n};\n#endif\n\nstatic void\nsigterm_catch(int sig)\n{\n}\n\nint main(int argc, char **argv)\n{\n\tstruct lws_context_creation_info info;\n\tstruct lws_vhost *vhost;\n\tchar interface_name[128] \u003d \u0022\u0022;\n\tconst char *iface \u003d NULL;\n\tchar cert_path[1024] \u003d \u0022\u0022;\n\tchar key_path[1024] \u003d \u0022\u0022;\n\tchar ca_path[1024] \u003d \u0022\u0022;\n#ifndef LWS_NO_DAEMONIZE\n\tint daemonize \u003d 0;\n#endif\n\tuint64_t opts \u003d 0;\n\tint use_ssl \u003d 0;\n\tuid_t uid \u003d (uid_t)-1;\n\tgid_t gid \u003d (gid_t)-1;\n\tint n \u003d 0;\n\n\t/*\n\t * take care to zero down the info struct, he contains random garbaage\n\t * from the stack otherwise\n\t */\n\tmemset(\u0026info, 0, sizeof info);\n\tinfo.port \u003d 7681;\n\n\twhile (n \u003e\u003d 0) {\n#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)\n\t\tn \u003d getopt_long(argc, argv, \u0022eci:hsap:d:DC:K:A:R:vu:g:kU:niIr:\u0022, options, NULL);\n#else\n\t\tn \u003d getopt(argc, argv, \u0022eci:hsap:d:DC:K:A:R:vu:g:kU:nIr:\u0022);\n#endif\n\t\tif (n \u003c 0)\n\t\t\tcontinue;\n\t\tswitch (n) {\n\t\tcase 'e':\n\t\t\topts |\u003d LWS_SERVER_OPTION_LIBEV;\n\t\t\tbreak;\n#ifndef LWS_NO_DAEMONIZE\n\t\tcase 'D':\n\t\t\tdaemonize \u003d 1;\n\t\t\tbreak;\n#endif\n\t\tcase 'u':\n\t\t\tuid \u003d (uid_t)atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'g':\n\t\t\tgid \u003d (gid_t)atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'd':\n\t\t\tdebug_level \u003d atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\t/* no dumb increment send */\n\t\t\ttest_options |\u003d 1;\n\t\t\tbreak;\n\t\tcase 'I':\n\t\t\tsignal(SIGTERM, sigterm_catch);\n\t\t\tbreak;\n\t\tcase 'r':\n\t\t\tresource_path \u003d optarg;\n\t\t\tbreak;\n\t\tcase 's':\n\t\t\tuse_ssl \u003d 1;\n\t\t\topts |\u003d LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;\n\t\t\tbreak;\n\t\tcase 'a':\n\t\t\topts |\u003d LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tinfo.port \u003d atoi(optarg);\n\t\t\tbreak;\n\t\tcase 'i':\n\t\t\tlws_strncpy(interface_name, optarg, sizeof interface_name);\n\t\t\tiface \u003d interface_name;\n\t\t\tbreak;\n\t\tcase 'U':\n\t\t\tlws_strncpy(interface_name, optarg, sizeof interface_name);\n\t\t\tiface \u003d interface_name;\n\t\t\topts |\u003d LWS_SERVER_OPTION_UNIX_SOCK;\n\t\t\tbreak;\n\t\tcase 'k':\n\t\t\tinfo.bind_iface \u003d 1;\n#if defined(LWS_HAVE_SYS_CAPABILITY_H) \u0026\u0026 defined(LWS_HAVE_LIBCAP)\n\t\t\tinfo.caps[0] \u003d CAP_NET_RAW;\n\t\t\tinfo.count_caps \u003d 1;\n#endif\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\tclose_testing \u003d 1;\n\t\t\tfprintf(stderr, \u0022 Close testing mode -- closes on \u0022\n\t\t\t\t\t \u0022client after 50 dumb increments\u0022\n\t\t\t\t\t \u0022and suppresses lws_mirror spam\u005cn\u0022);\n\t\t\tbreak;\n\t\tcase 'C':\n\t\t\tlws_strncpy(cert_path, optarg, sizeof(cert_path));\n\t\t\tbreak;\n\t\tcase 'K':\n\t\t\tlws_strncpy(key_path, optarg, sizeof(key_path));\n\t\t\tbreak;\n\t\tcase 'A':\n\t\t\tlws_strncpy(ca_path, optarg, sizeof(ca_path));\n\t\t\tbreak;\n#if defined(LWS_WITH_TLS)\n\t\tcase 'v':\n\t\t\tuse_ssl \u003d 1;\n\t\t\topts |\u003d LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;\n\t\t\tbreak;\n\n#if defined(LWS_HAVE_SSL_CTX_set1_param)\n\t\tcase 'R':\n\t\t\tlws_strncpy(crl_path, optarg, sizeof(crl_path));\n\t\t\tbreak;\n#endif\n#endif\n\t\tcase 'h':\n\t\t\tfprintf(stderr, \u0022Usage: test-server \u0022\n\t\t\t\t\t\u0022[--port\u003d\u003cp\u003e] [--ssl] \u0022\n\t\t\t\t\t\u0022[-d \u003clog bitfield\u003e]\u005cn\u0022);\n\t\t\texit(1);\n\t\t}\n\t}\n\n#if !defined(LWS_NO_DAEMONIZE) \u0026\u0026 !defined(WIN32)\n\t/*\n\t * normally lock path would be /var/lock/lwsts or similar, to\n\t * simplify getting started without having to take care about\n\t * permissions or running as root, set to /tmp/.lwsts-lock\n\t */\n\tif (daemonize \u0026\u0026 lws_daemonize(\u0022/tmp/.lwsts-lock\u0022)) {\n\t\tfprintf(stderr, \u0022Failed to daemonize\u005cn\u0022);\n\t\treturn 10;\n\t}\n#endif\n\n\tsignal(SIGINT, sighandler);\n#if !defined(WIN32) \u0026\u0026 !defined(_WIN32)\n\t/* because windows is too dumb to have SIGUSR1... */\n\t/* dynamic vhost create / destroy toggle (on port + 1) */\n\tsignal(SIGUSR1, sighandler);\n#endif\n\n\t/* tell the library what debug level to emit and to send it to stderr */\n\tlws_set_log_level(debug_level, NULL);\n\n\tlwsl_notice(\u0022libwebsockets test server - license MIT\u005cn\u0022);\n\tlwsl_notice(\u0022(C) Copyright 2010-2018 Andy Green \u003candy@warmcat.com\u003e\u005cn\u0022);\n\n\tprintf(\u0022Using resource path \u005c\u0022%s\u005c\u0022\u005cn\u0022, resource_path);\n#if defined(LWS_WITH_EXTERNAL_POLL)\n#if !defined(WIN32) \u0026\u0026 !defined(_WIN32) \u0026\u0026 !defined(__ANDROID__)\n\tmax_poll_elements \u003d getdtablesize();\n#else\n\tmax_poll_elements \u003d sysconf(_SC_OPEN_MAX);\n#endif\n\tpollfds \u003d malloc((unsigned int)max_poll_elements * sizeof (struct lws_pollfd));\n\tfd_lookup \u003d malloc((unsigned int)max_poll_elements * sizeof (int));\n\tif (pollfds \u003d\u003d NULL || fd_lookup \u003d\u003d NULL) {\n\t\tlwsl_err(\u0022Out of memory pollfds\u003d%d\u005cn\u0022, max_poll_elements);\n\t\treturn -1;\n\t}\n\tfor (n \u003d 0; n \u003c max_poll_elements; n++)\n\t\tpollfds[n].fd \u003d LWS_SOCK_INVALID;\n\tcount_pollfds \u003d 0;\n#endif\n\n\tinfo.iface \u003d iface;\n\tinfo.protocols \u003d protocols;\n\n#if defined(LWS_WITH_TLS)\n\tinfo.ssl_cert_filepath \u003d NULL;\n\tinfo.ssl_private_key_filepath \u003d NULL;\n\n\tif (use_ssl) {\n\t\tif (strlen(resource_path) \u003e sizeof(cert_path) - 32) {\n\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n\t\t\treturn -1;\n\t\t}\n\t\tif (!cert_path[0])\n\t\t\tsprintf(cert_path, \u0022%s/libwebsockets-test-server.pem\u0022,\n\t\t\t\t\t\t\t\tresource_path);\n\t\tif (strlen(resource_path) \u003e sizeof(key_path) - 32) {\n\t\t\tlwsl_err(\u0022resource path too long\u005cn\u0022);\n\t\t\treturn -1;\n\t\t}\n\t\tif (!key_path[0])\n\t\t\tsprintf(key_path, \u0022%s/libwebsockets-test-server.key.pem\u0022,\n\t\t\t\t\t\t\t\tresource_path);\n#if defined(LWS_WITH_TLS)\n\t\tinfo.ssl_cert_filepath \u003d cert_path;\n\t\tinfo.ssl_private_key_filepath \u003d key_path;\n\t\tif (ca_path[0])\n\t\t\tinfo.ssl_ca_filepath \u003d ca_path;\n#endif\n\t}\n#endif\n\tinfo.gid \u003d gid;\n\tinfo.uid \u003d uid;\n\tinfo.options \u003d opts | LWS_SERVER_OPTION_VALIDATE_UTF8 | LWS_SERVER_OPTION_EXPLICIT_VHOSTS;\n#if defined(LWS_ROLE_WS) \u0026\u0026 !defined(LWS_WITHOUT_EXTENSIONS)\n\tinfo.extensions \u003d exts;\n#endif\n\tinfo.timeout_secs \u003d 5;\n#if defined(LWS_WITH_TLS)\n\tinfo.ssl_cipher_list \u003d \u0022ECDHE-ECDSA-AES256-GCM-SHA384:\u0022\n\t\t\t \u0022ECDHE-RSA-AES256-GCM-SHA384:\u0022\n\t\t\t \u0022DHE-RSA-AES256-GCM-SHA384:\u0022\n\t\t\t \u0022ECDHE-RSA-AES256-SHA384:\u0022\n\t\t\t \u0022HIGH:!aNULL:!eNULL:!EXPORT:\u0022\n\t\t\t \u0022!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:\u0022\n\t\t\t \u0022!SHA1:!DHE-RSA-AES128-GCM-SHA256:\u0022\n\t\t\t \u0022!DHE-RSA-AES128-SHA256:\u0022\n\t\t\t \u0022!AES128-GCM-SHA256:\u0022\n\t\t\t \u0022!AES128-SHA256:\u0022\n\t\t\t \u0022!DHE-RSA-AES256-SHA256:\u0022\n\t\t\t \u0022!AES256-GCM-SHA384:\u0022\n\t\t\t \u0022!AES256-SHA256\u0022;\n#endif\n\tinfo.mounts \u003d \u0026mount;\n#if defined(LWS_WITH_PEER_LIMITS)\n\tinfo.ip_limit_ah \u003d 128; /* for testing */\n\tinfo.ip_limit_wsi \u003d 800; /* for testing */\n#endif\n\n\tif (use_ssl)\n\t\t/* redirect guys coming on http */\n\t\tinfo.options |\u003d LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS;\n\n\tcontext \u003d lws_create_context(\u0026info);\n\tif (context \u003d\u003d NULL) {\n\t\tlwsl_err(\u0022libwebsocket init failed\u005cn\u0022);\n\t\treturn -1;\n\t}\n\n\tinfo.pvo \u003d \u0026pvo;\n\n\tvhost \u003d lws_create_vhost(context, \u0026info);\n\tif (!vhost) {\n\t\tlwsl_err(\u0022vhost creation failed\u005cn\u0022);\n\t\treturn -1;\n\t}\n\n\t/*\n\t * For testing dynamic vhost create / destroy later, we use port + 1\n\t * Normally if you were creating more vhosts, you would set info.name\n\t * for each to be the hostname external clients use to reach it\n\t */\n\n\tinfo.port++;\n\n#if defined(LWS_WITH_CLIENT) \u0026\u0026 defined(LWS_WITH_TLS)\n\tlws_init_vhost_client_ssl(\u0026info, vhost);\n#endif\n\n\t/* this shows how to override the lws file operations.\tYou don't need\n\t * to do any of this unless you have a reason (eg, want to serve\n\t * compressed files without decompressing the whole archive)\n\t */\n\t/* stash original platform fops */\n\tfops_plat \u003d *(lws_get_fops(context));\n\t/* override the active fops */\n\tlws_get_fops(context)-\u003eopen \u003d test_server_fops_open;\n\n\tn \u003d 0;\n\twhile (n \u003e\u003d 0 \u0026\u0026 !force_exit) {\n\t\tstruct timeval tv;\n\n\t\tgettimeofday(\u0026tv, NULL);\n\n\t\t/*\n\t\t * This provokes the LWS_CALLBACK_SERVER_WRITEABLE for every\n\t\t * live websocket connection using the DUMB_INCREMENT protocol,\n\t\t * as soon as it can take more packets (usually immediately)\n\t\t */\n\n#if defined(LWS_WITH_EXTERNAL_POLL)\n\t\t/*\n\t\t * this represents an existing server's single poll action\n\t\t * which also includes libwebsocket sockets\n\t\t */\n\n\t\t/* if needed, force-service wsis that may not have read all input */\n\t\tn \u003d lws_service_adjust_timeout(context, 5000, 0);\n\n\t\tn \u003d poll(pollfds, (nfds_t)count_pollfds, n);\n\t\tif (n \u003c 0)\n\t\t\tcontinue;\n\n\t\tif (n) {\n\t\t\tfor (n \u003d 0; n \u003c count_pollfds; n++)\n\t\t\t\tif (pollfds[n].revents)\n\t\t\t\t\t/*\n\t\t\t\t\t* returns immediately if the fd does not\n\t\t\t\t\t* match anything under libwebsockets\n\t\t\t\t\t* control\n\t\t\t\t\t*/\n\t\t\t\t\tif (lws_service_fd(context,\n\t\t\t\t\t\t\t \u0026pollfds[n]) \u003c 0)\n\t\t\t\t\t\tgoto done;\n\t\t}\n\n\t\tlws_service_tsi(context, -1, 0);\n#else\n\t\t/*\n\t\t * If libwebsockets sockets are all we care about,\n\t\t * you can use this api which takes care of the poll()\n\t\t * and looping through finding who needed service.\n\t\t */\n\n\t\tn \u003d lws_service(context, 0);\n#endif\n\n\t\tif (dynamic_vhost_enable \u0026\u0026 !dynamic_vhost) {\n\t\t\tlwsl_notice(\u0022creating dynamic vhost...\u005cn\u0022);\n\t\t\tdynamic_vhost \u003d lws_create_vhost(context, \u0026info);\n\t\t} else\n\t\t\tif (!dynamic_vhost_enable \u0026\u0026 dynamic_vhost) {\n\t\t\t\tlwsl_notice(\u0022destroying dynamic vhost...\u005cn\u0022);\n\t\t\t\tlws_vhost_destroy(dynamic_vhost);\n\t\t\t\tdynamic_vhost \u003d NULL;\n\t\t\t}\n\n\t}\n\n#if defined(LWS_WITH_EXTERNAL_POLL)\ndone:\n#endif\n\n\tlws_context_destroy(context);\n\n\tlwsl_notice(\u0022libwebsockets-test-server exited cleanly\u005cn\u0022);\n\n\treturn 0;\n}\n","s":{"c":1711704327,"u": 472}}
],"g": 2848,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}