Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1594315897, "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":"622f22a03831ba700b08d72ca9a94a0c", "oid":{ "oid": "1be6b4d075e63cbe9d4c4f9696a0a7647c475068", "alias": [ "refs/heads/master"]},"blobname": "minimal-examples/http-server/minimal-http-server-dynamic/minimal-http-server-dynamic.c", "blob": "/*\n * lws-minimal-http-server-dynamic\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 * This demonstrates a minimal http server that can produce dynamic http\n * content as well as static content.\n *\n * To keep it simple, it serves the static stuff from the subdirectory\n * \u0022./mount-origin\u0022 of the directory it was started in.\n *\n * You can change that by changing mount.origin below.\n */\n\n#include \u003clibwebsockets.h\u003e\n#include \u003cstring.h\u003e\n#include \u003csignal.h\u003e\n#include \u003ctime.h\u003e\n\n/*\n * Unlike ws, http is a stateless protocol. This pss only exists for the\n * duration of a single http transaction. With http/1.1 keep-alive and http/2,\n * that is unrelated to (shorter than) the lifetime of the network connection.\n */\nstruct pss {\n\tchar path[128];\n\n\tint times;\n\tint budget;\n\n\tint content_lines;\n};\n\nstatic int interrupted;\n\nstatic int\ncallback_dynamic_http(struct lws *wsi, enum lws_callback_reasons reason,\n\t\t\tvoid *user, void *in, size_t len)\n{\n\tstruct pss *pss \u003d (struct pss *)user;\n\tuint8_t buf[LWS_PRE + 2048], *start \u003d \u0026buf[LWS_PRE], *p \u003d start,\n\t\t*end \u003d \u0026buf[sizeof(buf) - LWS_PRE - 1];\n\ttime_t t;\n\tint n;\n\n\tswitch (reason) {\n\tcase LWS_CALLBACK_HTTP:\n\n\t\t/* in contains the url part after our mountpoint /dyn, if any */\n\t\tlws_snprintf(pss-\u003epath, sizeof(pss-\u003epath), \u0022%s\u0022, (const char *)in);\n\n\t\tlws_get_peer_simple(wsi, (char *)buf, sizeof(buf));\n\t\tlwsl_notice(\u0022%s: HTTP: connection %s\u005cn\u0022, __func__, (const char *)buf);\n\n\t\t/*\n\t\t * prepare and write http headers... with regards to content-\n\t\t * length, there are three approaches:\n\t\t *\n\t\t * - http/1.0 or connection:close: no need, but no pipelining\n\t\t * - http/1.1 or connected:keep-alive\n\t\t * (keep-alive is default for 1.1): content-length required\n\t\t * - http/2: no need, LWS_WRITE_HTTP_FINAL closes the stream\n\t\t *\n\t\t * giving the api below LWS_ILLEGAL_HTTP_CONTENT_LEN instead of\n\t\t * a content length forces the connection response headers to\n\t\t * send back \u0022connection: close\u0022, disabling keep-alive.\n\t\t *\n\t\t * If you know the final content-length, it's always OK to give\n\t\t * it and keep-alive can work then if otherwise possible. But\n\t\t * often you don't know it and avoiding having to compute it\n\t\t * at header-time makes life easier at the server.\n\t\t */\n\t\tif (lws_add_http_common_headers(wsi, HTTP_STATUS_OK,\n\t\t\t\t\u0022text/html\u0022,\n\t\t\t\tLWS_ILLEGAL_HTTP_CONTENT_LEN, /* no content len */\n\t\t\t\t\u0026p, end))\n\t\t\treturn 1;\n\t\tif (lws_finalize_write_http_header(wsi, start, \u0026p, end))\n\t\t\treturn 1;\n\n\t\tpss-\u003etimes \u003d 0;\n\t\tpss-\u003ebudget \u003d atoi((char *)in + 1);\n\t\tpss-\u003econtent_lines \u003d 0;\n\t\tif (!pss-\u003ebudget)\n\t\t\tpss-\u003ebudget \u003d 10;\n\n\t\t/* write the body separately */\n\t\tlws_callback_on_writable(wsi);\n\n\t\treturn 0;\n\n\tcase LWS_CALLBACK_HTTP_WRITEABLE:\n\n\t\tif (!pss || pss-\u003etimes \u003e pss-\u003ebudget)\n\t\t\tbreak;\n\n\t\t/*\n\t\t * We send a large reply in pieces of around 2KB each.\n\t\t *\n\t\t * For http/1, it's possible to send a large buffer at once,\n\t\t * but lws will malloc() up a temp buffer to hold any data\n\t\t * that the kernel didn't accept in one go. This is expensive\n\t\t * in memory and cpu, so it's better to stage the creation of\n\t\t * the data to be sent each time.\n\t\t *\n\t\t * For http/2, large data frames would block the whole\n\t\t * connection, not just the stream and are not allowed. Lws\n\t\t * will call back on writable when the stream both has transmit\n\t\t * credit and the round-robin fair access for sibling streams\n\t\t * allows it.\n\t\t *\n\t\t * For http/2, we must send the last part with\n\t\t * LWS_WRITE_HTTP_FINAL to close the stream representing\n\t\t * this transaction.\n\t\t */\n\t\tn \u003d LWS_WRITE_HTTP;\n\t\tif (pss-\u003etimes \u003d\u003d pss-\u003ebudget)\n\t\t\tn \u003d LWS_WRITE_HTTP_FINAL;\n\n\t\tif (!pss-\u003etimes) {\n\t\t\t/*\n\t\t\t * the first time, we print some html title\n\t\t\t */\n\t\t\tt \u003d time(NULL);\n\t\t\t/*\n\t\t\t * to work with http/2, we must take care about LWS_PRE\n\t\t\t * valid behind the buffer we will send.\n\t\t\t */\n\t\t\tp +\u003d lws_snprintf((char *)p, end - p, \u0022\u003chtml\u003e\u0022\n\t\t\t\t\u0022\u003chead\u003e\u003cmeta charset\u003dutf-8 \u0022\n\t\t\t\t\u0022http-equiv\u003d\u005c\u0022Content-Language\u005c\u0022 \u0022\n\t\t\t\t\u0022content\u003d\u005c\u0022en\u005c\u0022/\u003e\u003c/head\u003e\u003cbody\u003e\u0022\n\t\t\t\t\u0022\u003cimg src\u003d\u005c\u0022/libwebsockets.org-logo.svg\u005c\u0022\u003e\u0022\n\t\t\t\t\u0022\u003cbr\u003eDynamic content for '%s' from mountpoint.\u0022\n\t\t\t\t\u0022\u003cbr\u003eTime: %s\u003cbr\u003e\u003cbr\u003e\u0022\n\t\t\t\t\u0022\u003c/body\u003e\u003c/html\u003e\u0022, pss-\u003epath, ctime(\u0026t));\n\t\t} else {\n\t\t\t/*\n\t\t\t * after the first time, we create bulk content.\n\t\t\t *\n\t\t\t * Again we take care about LWS_PRE valid behind the\n\t\t\t * buffer we will send.\n\t\t\t */\n\n\t\t\twhile (lws_ptr_diff(end, p) \u003e 80)\n\t\t\t\tp +\u003d lws_snprintf((char *)p, end - p,\n\t\t\t\t\t\u0022%d.%d: this is some content... \u0022,\n\t\t\t\t\tpss-\u003etimes, pss-\u003econtent_lines++);\n\n\t\t\tp +\u003d lws_snprintf((char *)p, end - p, \u0022\u003cbr\u003e\u003cbr\u003e\u0022);\n\t\t}\n\n\t\tpss-\u003etimes++;\n\t\tif (lws_write(wsi, (uint8_t *)start, lws_ptr_diff(p, start), n) !\u003d\n\t\t\t\tlws_ptr_diff(p, start))\n\t\t\treturn 1;\n\n\t\t/*\n\t\t * HTTP/1.0 no keepalive: close network connection\n\t\t * HTTP/1.1 or HTTP1.0 + KA: wait / process next transaction\n\t\t * HTTP/2: stream ended, parent connection remains up\n\t\t */\n\t\tif (n \u003d\u003d LWS_WRITE_HTTP_FINAL) {\n\t\t if (lws_http_transaction_completed(wsi))\n\t\t\treturn -1;\n\t\t} else\n\t\t\tlws_callback_on_writable(wsi);\n\n\t\treturn 0;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn lws_callback_http_dummy(wsi, reason, user, in, len);\n}\n\nstatic const struct lws_protocols protocol \u003d\n\t{ \u0022http\u0022, callback_dynamic_http, sizeof(struct pss), 0 };\n\nstatic const struct lws_protocols *pprotocols[] \u003d { \u0026protocol, NULL };\n\n/* override the default mount for /dyn in the URL space */\n\nstatic const struct lws_http_mount mount_dyn \u003d {\n\t/* .mount_next */\t\tNULL,\t\t/* linked-list \u0022next\u0022 */\n\t/* .mountpoint */\t\t\u0022/dyn\u0022,\t\t/* mountpoint URL */\n\t/* .origin */\t\t\tNULL,\t/* protocol */\n\t/* .def */\t\t\tNULL,\n\t/* .protocol */\t\t\t\u0022http\u0022,\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/* .origin_protocol */\t\tLWSMPRO_CALLBACK, /* dynamic */\n\t/* .mountpoint_len */\t\t4,\t\t/* char count */\n\t/* .basic_auth_login_file */\tNULL,\n};\n\n/* default mount serves the URL space from ./mount-origin */\n\nstatic const struct lws_http_mount mount \u003d {\n\t/* .mount_next */\t\u0026mount_dyn,\t\t/* linked-list \u0022next\u0022 */\n\t/* .mountpoint */\t\t\u0022/\u0022,\t\t/* mountpoint URL */\n\t/* .origin */\t\t\u0022./mount-origin\u0022,\t/* serve from dir */\n\t/* .def */\t\t\t\u0022index.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/* .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\nvoid sigint_handler(int sig)\n{\n\tinterrupted \u003d 1;\n}\n\nint main(int argc, const char **argv)\n{\n\tstruct lws_context_creation_info info;\n\tstruct lws_context *context;\n\tconst char *p;\n\tint n \u003d 0, logs \u003d LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE\n\t\t\t/* for LLL_ verbosity above NOTICE to be built into lws,\n\t\t\t * lws must have been configured and built with\n\t\t\t * -DCMAKE_BUILD_TYPE\u003dDEBUG instead of \u003dRELEASE */\n\t\t\t/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */\n\t\t\t/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */\n\t\t\t/* | LLL_DEBUG */;\n\n\tsignal(SIGINT, sigint_handler);\n\n\tif ((p \u003d lws_cmdline_option(argc, argv, \u0022-d\u0022)))\n\t\tlogs \u003d atoi(p);\n\n\tlws_set_log_level(logs, NULL);\n\tlwsl_user(\u0022LWS minimal http server dynamic | visit http://localhost:7681\u005cn\u0022);\n\n\tmemset(\u0026info, 0, sizeof info); /* otherwise uninitialized garbage */\n\tinfo.options \u003d LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |\n\t\t LWS_SERVER_OPTION_EXPLICIT_VHOSTS |\n\t\tLWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;\n\n\t/* for testing ah queue, not useful in real world */\n\tif (lws_cmdline_option(argc, argv, \u0022--ah1\u0022))\n\t\tinfo.max_http_header_pool \u003d 1;\n\n\tcontext \u003d lws_create_context(\u0026info);\n\tif (!context) {\n\t\tlwsl_err(\u0022lws init failed\u005cn\u0022);\n\t\treturn 1;\n\t}\n\n\t/* http on 7681 */\n\n\tinfo.port \u003d 7681;\n\tinfo.pprotocols \u003d pprotocols;\n\tinfo.mounts \u003d \u0026mount;\n\tinfo.vhost_name \u003d \u0022http\u0022;\n\n\tif (!lws_create_vhost(context, \u0026info)) {\n\t\tlwsl_err(\u0022Failed to create tls vhost\u005cn\u0022);\n\t\tgoto bail;\n\t}\n\n\t/* https on 7682 */\n\n\tinfo.port \u003d 7682;\n\tinfo.error_document_404 \u003d \u0022/404.html\u0022;\n#if defined(LWS_WITH_TLS)\n\tinfo.ssl_cert_filepath \u003d \u0022localhost-100y.cert\u0022;\n\tinfo.ssl_private_key_filepath \u003d \u0022localhost-100y.key\u0022;\n#endif\n\tinfo.vhost_name \u003d \u0022localhost\u0022;\n\n\tif (!lws_create_vhost(context, \u0026info)) {\n\t\tlwsl_err(\u0022Failed to create tls vhost\u005cn\u0022);\n\t\tgoto bail;\n\t}\n\n\twhile (n \u003e\u003d 0 \u0026\u0026 !interrupted)\n\t\tn \u003d lws_service(context, 0);\n\nbail:\n\tlws_context_destroy(context);\n\n\treturn 0;\n}\n","s":{"c":1594315897,"u": 452}} ],"g": 2276,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}