From 42e8b189dcbd1f2b0b38180fe36ec9cc0c944dec Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 22 Apr 2016 08:53:49 +0800 Subject: [PATCH] http cache policy This allows mounts to define the caching policy of the files inside them. Support is added in lwsws for controlling it from the config files. The api for serializing a mount struct opaquely is removed and lws_http_mount struct made public... it was getting out of control trying to hide the options. Signed-off-by: Andy Green --- CMakeLists.txt | 2 +- README.lwsws.md | 21 +++- lib/context.c | 44 -------- lib/header.c | 7 +- lib/libwebsockets.c | 12 ++- lib/libwebsockets.h | 28 +++-- lib/private-libwebsockets.h | 18 +--- lib/server.c | 76 ++++++++++++-- lwsws/conf.c | 82 ++++++++++----- lwsws/etc-lwsws-conf-EXAMPLE | 1 + lwsws/etc-lwsws-conf.d-localhost-EXAMPLE | 125 +++++++++++++++++++---- plugins/lwsws-logo.png | Bin 0 -> 5172 bytes plugins/server-status.html | 24 +++-- 13 files changed, 303 insertions(+), 137 deletions(-) create mode 100644 plugins/lwsws-logo.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 66126012..0b244a7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1405,7 +1405,7 @@ if (LWS_WITH_PLUGINS) DESTINATION share/libwebsockets-test-server/plugins COMPONENT plugins) if (LWS_WITH_SERVER_STATUS) - install(FILES plugins/server-status.html + install(FILES plugins/server-status.html;plugins/lwsws-logo.png DESTINATION share/libwebsockets-test-server/server-status COMPONENT examples) endif() diff --git a/README.lwsws.md b/README.lwsws.md index 15a8bd31..82227fdf 100644 --- a/README.lwsws.md +++ b/README.lwsws.md @@ -216,7 +216,13 @@ Mount protocols are used to control what kind of translation happens would cause the url /git/myrepo to pass "myrepo" to the cgi /var/www/cgi-bin/cgit and send the results to the client. - When using a cgi:// protcol origin at a mountpoint, you may also give cgi environment variables specific to the mountpoint like this +Note: currently only a fixed set of mimetypes are supported. + + +Other mount options +------------------- + +1) When using a cgi:// protcol origin at a mountpoint, you may also give cgi environment variables specific to the mountpoint like this ``` { @@ -231,14 +237,23 @@ Mount protocols are used to control what kind of translation happens This allows you to customize one cgi depending on the mountpoint (and / or vhost). - It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this +2) It's also possible to set the cgi timeout (in secs) per cgi:// mount, like this ``` "cgi-timeout": "30" ``` +3) Cache policy of the files in the mount can also be set. If no +options are given, the content is marked uncacheable. -Note: currently only a fixed set of mimetypes are supported. + { + "mountpoint": "/", + "origin": "file:///var/www/mysite.com", + "cache-max-age": "60", # seconds + "cache-reuse": "1", # allow reuse at client at all + "cache-revalidate": "1", # check it with server each time + "cache-intermediaries": "1" # allow intermediary caches to hold + } Plugins diff --git a/lib/context.c b/lib/context.c index 8ee5ffa7..d95bbe57 100644 --- a/lib/context.c +++ b/lib/context.c @@ -49,50 +49,6 @@ static const char * const mount_protocols[] = { ">https://", }; -LWS_VISIBLE LWS_EXTERN int -lws_write_http_mount(struct lws_http_mount *next, struct lws_http_mount **res, - void *store, const char *mountpoint, const char *origin, - const char *def, struct lws_protocol_vhost_options *cgienv, - int cgi_timeout) -{ - struct lws_http_mount *m; - void *orig = store; - unsigned long l = (unsigned long)store; - int n; - - if (l & 15) - l += 16 - (l & 15); - - store = (void *)l; - m = (struct lws_http_mount *)store; - *res = m; - - m->def = def; - m->mountpoint = mountpoint; - m->mountpoint_len = (unsigned char)strlen(mountpoint); - m->mount_next = NULL; - m->cgienv = cgienv; - m->cgi_timeout = cgi_timeout; - - if (next) - next->mount_next = m; - - for (n = 0; n < ARRAY_SIZE(mount_protocols); n++) - if (!strncmp(origin, mount_protocols[n], - strlen(mount_protocols[n]))) { - m->origin_protocol = n; - m->origin = origin + strlen(mount_protocols[n]); - break; - } - - if (n == ARRAY_SIZE(mount_protocols)) { - lwsl_err("unsupported protocol:// %s\n", origin); - return 0; /* ie, fail */ - } - - return ((char *)store + sizeof(*m)) - (char *)orig; -} - LWS_VISIBLE void * lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot, int size) diff --git a/lib/header.c b/lib/header.c index 70058d19..9bc4b7df 100644 --- a/lib/header.c +++ b/lib/header.c @@ -167,8 +167,11 @@ lws_add_http_header_status(struct lws *wsi, unsigned int code, if (code == 200) description = "OK"; - if (code >= 300 && code < 400) - description = "Redirect"; + if (code == 304) + description = "Not Modified"; + else + if (code >= 300 && code < 400) + description = "Redirect"; if (wsi->u.http.request_version < ARRAY_SIZE(hver)) p1 = hver[wsi->u.http.request_version]; diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 43f367d6..a4b3fbc1 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -2395,11 +2395,19 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len) buf += snprintf(buf, end - buf, ","); buf += snprintf(buf, end - buf, "\n {\n \"mountpoint\":\"%s\",\n" - " \"origin\":\"%s%s\"\n" + " \"origin\":\"%s%s\",\n" + " \"cache_max_age\":\"%d\",\n" + " \"cache_reuse\":\"%d\",\n" + " \"cache_revalidate\":\"%d\",\n" + " \"cache_intermediaries\":\"%d\"\n" , m->mountpoint, prots[m->origin_protocol], - m->origin); + m->origin, + m->cache_max_age, + m->cache_reusable, + m->cache_revalidate, + m->cache_intermediaries); if (m->def) buf += snprintf(buf, end - buf, ",\n \"default\":\"%s\"", diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 6dd32a5e..78832d74 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -1367,6 +1367,25 @@ struct lws_protocol_vhost_options { const char *value; }; +struct lws_http_mount { + struct lws_http_mount *mount_next; + const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */ + const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com" */ + const char *def; /* default target, eg, "index.html" */ + + struct lws_protocol_vhost_options *cgienv; + + int cgi_timeout; + int cache_max_age; + + unsigned int cache_reusable:1; + unsigned int cache_revalidate:1; + unsigned int cache_intermediaries:1; + + unsigned char origin_protocol; + unsigned char mountpoint_len; +}; + /** * struct lws_context_creation_info - parameters to create context with * @@ -1553,8 +1572,6 @@ struct lws_client_connect_info { void *_unused[4]; }; -struct lws_http_mount; - enum { LWSMPRO_HTTP, LWSMPRO_HTTPS, @@ -1564,13 +1581,6 @@ enum { LWSMPRO_REDIR_HTTPS, }; -LWS_VISIBLE LWS_EXTERN int -lws_write_http_mount(struct lws_http_mount *next, struct lws_http_mount **res, - void *store, const char *mountpoint, const char *origin, - const char *def, - struct lws_protocol_vhost_options *cgienv, - int cgi_timeout); - LWS_EXTERN int lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len); diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 82146706..5c3e4cc9 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -619,20 +619,6 @@ struct lws_context_per_thread { unsigned char tid; }; -struct lws_http_mount { - struct lws_http_mount *mount_next; - const char *mountpoint; /* mountpoint in http pathspace, eg, "/" */ - const char *origin; /* path to be mounted, eg, "/var/www/warmcat.com" */ - const char *def; /* default target, eg, "index.html" */ - - struct lws_protocol_vhost_options *cgienv; - - int cgi_timeout; - - unsigned char origin_protocol; - unsigned char mountpoint_len; -}; - /* * virtual host -related context information * vhostwide SSL context @@ -1252,6 +1238,7 @@ struct lws { #ifndef LWS_NO_CLIENT int chunk_remaining; #endif + unsigned int cache_secs; unsigned int hdr_parsing_completed:1; unsigned int http2_substream:1; @@ -1261,6 +1248,9 @@ struct lws { unsigned int rxflow_change_to:2; unsigned int more_rx_waiting:1; /* has to live here since ah may stick to end */ unsigned int conn_stat_done:1; + unsigned int cache_reuse:1; + unsigned int cache_revalidate:1; + unsigned int cache_intermediaries:1; #ifdef LWS_WITH_ACCESS_LOG unsigned int access_log_pending:1; #endif diff --git a/lib/server.c b/lib/server.c index 5eafb583..94621f5c 100644 --- a/lib/server.c +++ b/lib/server.c @@ -133,7 +133,7 @@ lws_context_init_server(struct lws_context_creation_info *info, #if LWS_POSIX listen(wsi->sock, LWS_SOMAXCONN); - } /* for each thread able to independently lister */ + } /* for each thread able to independently listen */ #else mbed3_tcp_stream_bind(wsi->sock, info->port, wsi); #endif @@ -231,9 +231,10 @@ int lws_http_serve(struct lws *wsi, char *uri, const char *origin) const char *mimetype; struct stat st; char path[256], sym[256]; + unsigned char *p = (unsigned char *)sym + 32 + LWS_PRE, *start = p; + unsigned char *end = p + sizeof(sym) - 32 - LWS_PRE; int n, spin = 0; - lwsl_notice("%s: %s %s\n", __func__, uri, origin); snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri); do { @@ -263,17 +264,54 @@ int lws_http_serve(struct lws *wsi, char *uri, const char *origin) } while ((S_IFMT & st.st_mode) != S_IFREG && spin < 5); - if (spin == 5) { + if (spin == 5) lwsl_err("symlink loop %s \n", path); + + n = sprintf(sym, "%08lX%08lX", (unsigned long)st.st_size, + (unsigned long)st.st_mtime); + + if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) { + /* + * he thinks he has some version of it already, + * check if the tag matches + */ + if (!strcmp(sym, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH))) { + + lwsl_notice("%s: ETAG match %s %s\n", __func__, + uri, origin); + + /* we don't need to send the payload */ + if (lws_add_http_header_status(wsi, 304, &p, end)) + return -1; + if (lws_add_http_header_by_token(wsi, + WSI_TOKEN_HTTP_ETAG, + (unsigned char *)sym, n, &p, end)) + return -1; + if (lws_finalize_http_header(wsi, &p, end)) + return -1; + + n = lws_write(wsi, start, p - start, + LWS_WRITE_HTTP_HEADERS); + if (n != (p - start)) { + lwsl_err("_write returned %d from %d\n", n, p - start); + return -1; + } + + return lws_http_transaction_completed(wsi); + } } + if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG, + (unsigned char *)sym, n, &p, end)) + return -1; + mimetype = get_mimetype(path); if (!mimetype) { lwsl_err("unknown mimetype for %s", path); goto bail; } - n = lws_serve_http_file(wsi, path, mimetype, NULL, 0); + n = lws_serve_http_file(wsi, path, mimetype, (char *)start, p - start); if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi))) return -1; /* error or can't reuse connection: close the socket */ @@ -620,11 +658,13 @@ lws_http_action(struct lws *wsi) n = strlen(s); if (s[0] == '\0' || (n == 1 && s[n - 1] == '/')) s = (char *)hit->def; - if (!s) s = "index.html"; - // lwsl_err("okok\n"); + wsi->cache_secs = hit->cache_max_age; + wsi->cache_reuse = hit->cache_reusable; + wsi->cache_revalidate = hit->cache_revalidate; + wsi->cache_intermediaries = hit->cache_intermediaries; n = lws_http_serve(wsi, s, hit->origin); } else @@ -1589,12 +1629,14 @@ LWS_VISIBLE int lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, const char *other_headers, int other_headers_len) { + static const char * const intermediates[] = { "private", "public" }; struct lws_context *context = lws_get_context(wsi); struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; + char cache_control[50], *cc = "no-store"; unsigned char *response = pt->serv_buf + LWS_PRE; unsigned char *p = response; unsigned char *end = p + LWS_MAX_SOCKET_IO_BUF - LWS_PRE; - int ret = 0; + int ret = 0, cclen = 8; wsi->u.http.fd = lws_plat_file_open(wsi, file, &wsi->u.http.filelen, O_RDONLY); @@ -1608,10 +1650,6 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_add_http_header_status(wsi, 200, &p, end)) return -1; - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER, - (unsigned char *)"libwebsockets", 13, - &p, end)) - return -1; if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)content_type, strlen(content_type), &p, end)) @@ -1619,6 +1657,22 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_add_http_header_content_length(wsi, wsi->u.http.filelen, &p, end)) return -1; + if (wsi->cache_secs && wsi->cache_reuse) { + if (wsi->cache_revalidate) { + cc = cache_control; + cclen = sprintf(cache_control, "%s max-age: %u", + intermediates[wsi->cache_intermediaries], + wsi->cache_secs); + } else { + cc = "no-cache"; + cclen = 8; + } + } + + if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CACHE_CONTROL, + (unsigned char *)cc, cclen, &p, end)) + return -1; + if (other_headers) { if ((end - p) < other_headers_len) return -1; diff --git a/lwsws/conf.c b/lwsws/conf.c index 6a391951..e3a1ada0 100644 --- a/lwsws/conf.c +++ b/lwsws/conf.c @@ -54,6 +54,10 @@ static const char * const paths_vhosts[] = { "vhosts[].mounts[].default", "vhosts[].mounts[].cgi-timeout", "vhosts[].mounts[].cgi-env[].*", + "vhosts[].mounts[].cache-max-age", + "vhosts[].mounts[].cache-reuse", + "vhosts[].mounts[].cache-revalidate", + "vhosts[].mounts[].cache-intermediaries", "vhosts[].ws-protocols[].*.*", "vhosts[].ws-protocols[].*", "vhosts[].ws-protocols[]", @@ -77,6 +81,10 @@ enum lejp_vhost_paths { LEJPVP_DEFAULT, LEJPVP_CGI_TIMEOUT, LEJPVP_CGI_ENV, + LEJPVP_MOUNT_CACHE_MAX_AGE, + LEJPVP_MOUNT_CACHE_REUSE, + LEJPVP_MOUNT_CACHE_REVALIDATE, + LEJPVP_MOUNT_CACHE_INTERMEDIARIES, LEJPVP_PROTOCOL_NAME_OPT, LEJPVP_PROTOCOL_NAME, LEJPVP_PROTOCOL, @@ -90,10 +98,9 @@ struct jpargs { const struct lws_extension *extensions; char *p, *end, valid; struct lws_http_mount *head, *last; - char *mountpoint, *origin, *def; + struct lws_protocol_vhost_options *pvo; - struct lws_protocol_vhost_options *mp_cgienv; - int cgi_timeout; + struct lws_http_mount m; }; static void * @@ -205,13 +212,8 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) } if (reason == LEJPCB_OBJECT_START && - ctx->path_match == LEJPVP_MOUNTS + 1) { - a->mountpoint = NULL; - a->origin = NULL; - a->def = NULL; - a->mp_cgienv = NULL; - a->cgi_timeout = 0; - } + ctx->path_match == LEJPVP_MOUNTS + 1) + memset(&a->m, 0, sizeof(a->m)); /* this catches, eg, vhosts[].ws-protocols[].xxx-protocol */ if (reason == LEJPCB_OBJECT_START && @@ -254,17 +256,38 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) if (reason == LEJPCB_OBJECT_END && ctx->path_match == LEJPVP_MOUNTS + 1) { - if (!a->mountpoint || !a->origin) { + static const char * const mount_protocols[] = { + "http://", + "https://", + "file://", + "cgi://", + ">http://", + ">https://", + }; + + if (!a->m.mountpoint || !a->m.origin) { lwsl_err("mountpoint and origin required\n"); return 1; } + m = lwsws_align(a); + memcpy(m, &a->m, sizeof(*m)); + if (a->last) + a->last->mount_next = m; - n = lws_write_http_mount(a->last, &m, a->p, a->mountpoint, - a->origin, a->def, a->mp_cgienv, - a->cgi_timeout); - if (!n) + for (n = 0; n < ARRAY_SIZE(mount_protocols); n++) + if (!strncmp(a->m.origin, mount_protocols[n], + strlen(mount_protocols[n]))) { + m->origin_protocol = n; + m->origin = a->m.origin + strlen(mount_protocols[n]); + break; + } + + if (n == ARRAY_SIZE(mount_protocols)) { + lwsl_err("unsupported protocol:// %s\n", a->m.origin); return 1; - a->p += n; + } + + a->p += sizeof(*m); if (!a->head) a->head = m; @@ -310,26 +333,39 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) a->info->log_filepath = a->p; break; case LEJPVP_MOUNTPOINT: - a->mountpoint = a->p; + a->m.mountpoint = a->p; + a->m.mountpoint_len = strlen(ctx->buf); break; case LEJPVP_ORIGIN: - a->origin = a->p; + a->m.origin = a->p; break; case LEJPVP_DEFAULT: - a->def = a->p; + a->m.def = a->p; break; + case LEJPVP_MOUNT_CACHE_MAX_AGE: + a->m.cache_max_age = atoi(ctx->buf); + return 0; + case LEJPVP_MOUNT_CACHE_REUSE: + a->m.cache_reusable = arg_to_bool(ctx->buf); + return 0; + case LEJPVP_MOUNT_CACHE_REVALIDATE: + a->m.cache_revalidate = arg_to_bool(ctx->buf); + return 0; + case LEJPVP_MOUNT_CACHE_INTERMEDIARIES: + a->m.cache_intermediaries = arg_to_bool(ctx->buf);; + return 0; case LEJPVP_CGI_TIMEOUT: - a->cgi_timeout = atoi(ctx->buf); + a->m.cgi_timeout = atoi(ctx->buf); return 0; case LEJPVP_KEEPALIVE_TIMEOUT: a->info->keepalive_timeout = atoi(ctx->buf); return 0; case LEJPVP_CGI_ENV: mp_cgienv = lwsws_align(a); - a->p += sizeof(*a->mp_cgienv); + a->p += sizeof(*a->m.cgienv); - mp_cgienv->next = a->mp_cgienv; - a->mp_cgienv = mp_cgienv; + mp_cgienv->next = a->m.cgienv; + a->m.cgienv = mp_cgienv; n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); mp_cgienv->name = a->p; diff --git a/lwsws/etc-lwsws-conf-EXAMPLE b/lwsws/etc-lwsws-conf-EXAMPLE index e6184d98..8cdf5d8a 100644 --- a/lwsws/etc-lwsws-conf-EXAMPLE +++ b/lwsws/etc-lwsws-conf-EXAMPLE @@ -8,6 +8,7 @@ "gid": "48", "interface": "eth0", "count-threads": "1", + "server-string": "lwsws", "init-ssl": "yes" } } diff --git a/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE b/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE index 43d0489d..86fad5ec 100644 --- a/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE +++ b/lwsws/etc-lwsws-conf.d-localhost-EXAMPLE @@ -1,28 +1,40 @@ +# comment + { "vhosts": [ { - "name": "localhost", - "port": "80", + "name": "libwebsockets.org", + "port": "443", + "host-ssl-key": "/etc/pki/tls/private/libwebsockets.org.key", + "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt", + "host-ssl-ca": "/etc/pki/tls/certs/libwebsockets.org.cer", + "access-log": "/var/log/httpd/lws-access-log", + "sts": "on", "mounts": [{ "mountpoint": "/", "origin": "file:///var/www/libwebsockets.org", - "default": "index.html" + "default": "index.html", + "cache-max-age": "60", + "cache-reuse": "1", + "cache-revalidate": "1", + "cache-intermediaries": "0" }, { + # this hooks us up to cgit cgi part "mountpoint": "/git", "origin": "cgi:///var/www/cgi-bin/cgit", "default": "/", - "cgi-env": [{ - "CGIT_CONFIG": "/etc/cgitrc/libwebsockets.org" - }] + "cgi-env": [{ + "CGIT_CONFIG": "/etc/cgitrc/git.libwebsockets.org" + }], + # we can also set up per-cgi process timeout + "cgi-timeout": "30" }, { - "mountpoint": "/cgit-data", + # this hooks us up to cgit static assets + "mountpoint": "/git/cgit-data", "origin": "file:///usr/share/cgit", "default": "/" }, { - "mountpoint": "/testcgi", - "origin": "cgi:///usr/local/share/libwebsockets-test-server/lws-cgi-test.sh" - }, { "mountpoint": "/mailman", - "origin": ">http://localhost/mailman/listinfo" + "origin": ">https://libwebsockets.org/mailman/listinfo" }, { "mountpoint": "/mailman/listinfo", "origin": "cgi:///usr/lib/mailman/cgi-bin/listinfo" @@ -59,41 +71,110 @@ }, { "mountpoint": "/pipermail", "origin": "file:///var/lib/mailman/archives/public", - "default": "index.html" + "default": "index.html" + }, { + # we used to have a trac, redirect anyone using it to github + "mountpoint": "/trac", + "origin": ">https://github.com/warmcat/libwebsockets" + }, { + "mountpoint": "/server-status", + "origin": "file:///usr/local/share/libwebsockets-test-server/server-status", + "default": "server-status.html" }, { "mountpoint": "/testserver", "origin": "file:///usr/local/share/libwebsockets-test-server", "default": "test.html" - }], + } + ], # which protocols are enabled for this vhost, and optional # vhost-specific config options for the protocol # "ws-protocols": [{ - "warmcat,timezoom": { + "dumb-increment-protocol": { "status": "ok" + }, + "lws-mirror-protocol": { + "status": "ok" + }, + "lws-status": { + "status": "ok" + }, + "lws-server-status": { + "status": "ok", + "update-ms": "5000" } + }], + "ws-extensions": [{ + "extension": "permessage-deflate" }] - }, + }, + + # redirect any guys coming in on http to https { - "name": "localhost", + "name": "libwebsockets.org", + "port": "80", + "sts": "on", + "mounts": [{ + "mountpoint": "/", + "origin": ">https://libwebsockets.org" + }] + }, + { + # the old test server ran this on :7681, put a redirect + # there to take us to the new location + "name": "libwebsockets.org", "port": "7681", "host-ssl-key": "/etc/pki/tls/private/libwebsockets.org.key", "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt", "host-ssl-ca": "/etc/pki/tls/certs/libwebsockets.org.cer", "mounts": [{ "mountpoint": "/", - "origin": ">https://localhost" + "origin": ">https://libwebsockets.org/testserver/" }] - }, + }, + + # old site for mailing list redirect to new one { - "name": "localhostx", + "name": "ml.libwebsockets.org", "port": "80", "mounts": [{ "mountpoint": "/", - "origin": ">https://localhost" + "origin": ">https://libwebsockets.org/mailman" + }] + }, + # old site for mailing list redirect to new one + { + "name": "ml.libwebsockets.org", + "port": "443", + "mounts": [{ + "mountpoint": "/", + "origin": ">https://libwebsockets.org/mailman" + }] + }, + + + # redirect any guys coming in on http to https + { + "name": "git.libwebsockets.org", + "port": "80", + "mounts": [{ + "mountpoint": "/", + "origin": ">https://libwebsockets.org/git" + }] + }, + { + # the old test server ran this on :7681, put a redirect + # there to take us to the new location + "name": "git.libwebsockets.org", + "port": "443", + "host-ssl-key": "/etc/pki/tls/private/libwebsockets.org.key", + "host-ssl-cert": "/etc/pki/tls/certs/libwebsockets.org.crt", + "host-ssl-ca": "/etc/pki/tls/certs/libwebsockets.org.cer", + "mounts": [{ + "mountpoint": "/", + "origin": ">https://libwebsockets.org/git" }] } - - ] + }] } diff --git a/plugins/lwsws-logo.png b/plugins/lwsws-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4e4188bc9cfdda7852c837d851c1300922f97800 GIT binary patch literal 5172 zcmWky1ymGW7#(7fa7jTz8kSN(5F`bpLkZ~)iJy=zL0m$*aRKR;E)k?tx*Mfdx=RqG z{^vV0J7?z1+xO;u_q*S{FHG&FJRF}IAA%sbqJoSDxF&)Vfs6C+cfdReT(DiAD{A6` z=8O9}6x`!EDd@RE5b@N%6N85lH4h$AxykCfy>hg2^E7j@ggiYxx&M1(=W1c*WXbL5 zVx77#Mh!t^Rf;lFnqFyphTdwLI%hXFHXbBSQq!dN*v#rAVVFu!Y5Z#+H ztlfR)^H!vRQncx&D&zv(jMVALvCd)2q_WCslpb8zkun{eIY=ha1$)7TrGpr2iH5D< zU|eUb@QQ8iv5iH~5u+B*k@}6r5Inko*AI}loe<6;mzlY_dBw#~73DWrriYG8X&6@( z$h@$yFgy&&<8L(l$lDipiS3|kO#T&FI{2T1C3$sqk_QhSEbr~X`M>z-2t!y5Ve9Kw z>?kE&1B1@_`6iRo)1To}KYoPMih7vNe{)V2c12)fVUbW!1kcaU-)PL)6>4%8PT4|8 zjUwN{vMq_4y1JFoY-!!<*LdqgsUb7QK5&WKs}slEwAK5&%;3%L?(Xr9jsQr=bKj6o z%q#Yb^~ie7e-pFQ(^kJP8X823r?y*c z6LxcTWrhgppQR}(D!wc0m+539b1=v7!hqC_32SQ4BI6KlQ0FoM{W z6#OF1@PQ?6b2oN>Pu8_yh!uaSB3_qy72% zKq`K#w(s9zCcZ~7dwcuk?QQ(~_wRp1q0Ej~`^0Gidyr>m9-t#53k!BZL4i>s7Z+D& z@?(oi>k+#1%gcY$Q%>Ukpp@Uy@qxhk_on*n?Cfu?FDxlW*=8Xd3986+QU8qOJN*2n zr?w0ToXQ$(hUE6(U>pcjaetvPWOh~;bdY3-q<6GX`3C<(KgmKID^Rdv3}n~a;AyRf1{-ok>pJBFTT`lOz-&V*a{Dm!9*#2$jM=voSJeU z4AFS^BXRFlmn^ez0IbWkMUpa{s!Wad}=4m>_bX;m#U~W|` z(mXytTJb$xmP)dWrWNfjEqxgO+Sr&bB0O9n{?Gn`1z2fvd{{|I$)}8r;erCh^fP-M zeSK>1zyHLbyPt;Bby_yqNeUW zbQ&Lz|9ysNZt5LM?VFyC=7Ygr+pu%Q#SSDTpiq%9F`qR#$wkdnO2azhMKQsh@V{}-vqj_1oG?{NYG{k>0u_!bx2 z(4B2LvTYK#cu;cVJ5j5Vj40QQVGLs5vRwI?=bR`eK|u=8LVK) z+e(s&9|ok7`HU7!2}hBIg=M+%phX%G>cdBm(7U^lqoZm;At4ejgB;JE(HYd*`#;Yn zwrpu>3DvE^J^%g6%y?+XAL|bC@Q{!!IRUHGfGxSvc?C%%ft{1lt| z`ZNLZz82v~N=V|4yF(beGqb~IP=>HDSK#O8CkjKZGhdzZ#}%Zc8w-_zr5O)aJp(elEDfA&PZbUl#A>w!-3ag!S;f^@k$*ykXRZQ>&K;38{i{ zmX;ly?&yHF56Q{pnr9vNTK*QReKLHBU?aGhq`y_56DwT6IySi_9ki5$^wb%x);2a= zJA&{;XcH7ze6LSuiqzQe7W-(%dGVDs3a~{$;NahGb#bMhr6?~u|*sUyRL6;9vvSuLHhdo)n#Q- zmuGuB@tRO_TAF?3ZFgwCc8T}?yf7h+ph}FU&!7FhL-&aZMNdzc4(#J$+C6;i%)hxY zyb-I3hjd=2yk)OY>LBwT8+ogxFJ)0S(kuJnIYwhFXGRlCa zDkJCM;)+N>ycplg`uv%VfPeu0@1qu4-lam66ch!_Jlx#tok9d;WMuBg>m!+}c6N5p zybh6CT3R`-KWY8`G%kf*3m2Z|?9En5em&TdlITHnFIvXui@+Iw_UbqKlJ*1HCzx>)t&-JRI%p?A!pG7{{i^XTZYhiznT~ zV3vN~o5fIFsF3^~>3cF%9-Mc-3qT7h=-`wTXA78 z-uicq(SeyMDaBuyj}8w_{rp;_P%%mm<3Y(@iDi^_L#!X7JAWS^{{j->V$tVd>*Jrp z!{y1MSBmj#YirnT08^etnJi21Z{Jl(INHKJbaj)5gKRx2=H}*dcK7O*5Q=}#&qJ$0 zdvp3{P)M`?9wKkBaA{R|9+j11VoCUI8k{u4n?(bW(ullu- z4}{~JJjzO}!n*kUw1r;d65qdbmm2$_3E}*=u{h5){7NhM=pwg}znNKE4?WfwYb;R@ zh~Af>s{!hL%_k%*Or6KDXhh_hKv|9Owjn%=!7b$%2VRY~O3$ zN>iyGR^u}UB6Bf>BQ?IFK&spJV!&%;W8q!P@2@vdRZL;LaWDE{IK>yT0D z5X_!vjN00^lM$?$3M>wews=-a`M2N(a|0xP%Mz7l~n<|vXWAO z3L>zs?rFJkbNC&i+<}>LBdpQKb3l;jezAhz!-rW7r-hA=YXpj9yxrzdVCf*X4MnA= z!|M&BNtor9!`Lz)D6gOZlUL>8-ojSFi&SEAau`bKG_-jp1R!iyd%gko&;Sv;y%OU; zs)jyjy&>1FCq3U6ML)@}rHCDXUDUg_$*)-dk3R{2uY)qR|P%>%!9P zRKywc{O3|o6J3tyj8%6e$#7h0DK_F@9xsxbl|3qgEE@L2$%$AcJ2MkKe9DiBiD_zP z#uzWpkIv4{P8M8h2IEQ9 zuJpL;luHF-2cYX%$r*?{mzL-yZq9SPjJMX;gX5UxJAl|FBqaRRWz^^aR~0|~*e(J@ zcx1EBA5f6ZPu7RL4x0bC_1h$@c1O`DC@W(@gUOGvCO)g)Khb#gN?lhMH>*>{j+mM{ zoZjyo!{6UOr?jDg8kBWeXXm3_c$f5MWNTerY>m1uZqqrF)1UI?4&PJMq0gm)#KpstvbE)0brHtL$9KaWr?Q(al`=PH0$RQD-KEEvHKv=Q z%gOqS$;nBGIAlNjp{c1UHZd`{%%HAgHJfN+b~d!Iuu%R13`3+` z!J2++{e{1ntZZ9%RKNv|;N8$D*_HA9ULFo9IXN6Ye*S;1Au%!0m}466>60f7U%vO;ftd?GGf*9RG);S6yD zu~^5cXVwDHURF_HU|>66GyEwq94BCezp$O1KCO}EUfsYg za3u77GyjgizP3gcUPTpS;jq+_4!+`ToGGYEDJd!A{r&&KnLQ>o4i=lAn>+evt;0&K z!%s>YngKwEftHuyy7~F}*liNmTdLS?neT7(29;F-Ch|0jyauvGfg}7eH+R&>mN^+` zhb!>9ml$)oAI0^(37~9i^~EQ?{GPW@EZ&5Qb%$!{>-QfXI{m%8oLE}QBq1RwEiUFO zHV6c&IvNoB`ue)LnvSTjs3<=pWA=%~0$E8*i}BrgIB<%f+OLO`b8W7!=Dn&15%oM+ z90CpocunKa<)b=XOdpujj#hehV9Gy#{IGFwcp)JnfrE|hW)OnIi3*>do=)R63y8j2 z@LZarN;*IHdd$PjEX{T>^iq8XxUXiv#bzI!8q!ve?;1s#n(X&J4y=L0-qv>eNb3Oj zndZXgq9P7UKB{-VzA`x7}=&UU3tO&Nd`{b#MCXr6{U z(|&mFUs%Wv{95PY;-Z?C5lFLNC>`VWt}rs$%p3{gd-sAsc3A-1De`u3Xy~!`@oV4P z>p!89k&`~C;7UXeY!y>fk=csj^G^1EdM+TPxFTIq%#S;S@JR9BOZjg7IhvlCki3JQV|x~?ux z(7;nlhY+IaZ_n?9M?|P=YfoS2D|qNv0Rol=J0!-fe(4}eZZ0mrinU6TKYq-!XryQL ze*2bBT-@j&YHKK*oP?xZt3-Q?bx5h!=g%9=WdO(1?a=UWCdlt>&RXQSqvJUt&^25- z<*OOuK3>2`$;ru$1K$E>F*qx$?n`2-}O({l+@JyU~8fvKYwg$>g!1F)P=c`kB{g`hWJlrb9a=6 zhK2&Z^+)9X9u}OGj0{iGkt`1QxhjjE?WwJe4Yui@R3L)bZN0q;&0<4x?Nd`)@{6OR z|I|)|3IBhe0rL0-1ilX3c*>Rn6UePs-IZnX+io1Bk=MbZcyLeHTglHgev7OirG)UZobWz4xWMx=XHj%2x2n zliz(CCJqh`O>SH9?N1x?^FJhU8*OW-{`VipD-8{=wSIC6JNiLtNm*GKaFco_CKXAa z)!20n4Ild1PE)zmr%_Q+iFxinAR{GhXgbY?qm;g1UHKN*?5p*yxp3=NW~nMzT3K~( zZrT7-T3c7=y3pY6=H#^8fc6EM4yP=1*Ne-;%%M7tFp4O}C89x-GN`@HK&P>I9$G_84Q)pnSzxiE@ z`1<-*I-#F`Yi#uNQ@Oe-F))XlLd`+1ms^MKW|=&eEXDXufD
-
+ + + @@ -164,7 +166,8 @@ function get_appropriate_ws_url() try { socket_status.onopen = function() { - } + document.getElementById("title").innerHTML = "Server Status (Active)"; + } socket_status.onmessage =function got_packet(msg) { document.getElementById("conninfo").innerHTML = "
"+msg.data+"
"; @@ -210,14 +213,24 @@ function get_appropriate_ws_url() "total http transactions " + san(jso.vhosts[n].trans) + "
" + "Upgrades to ws: " + san(jso.vhosts[n].ws_upg) + ", " + "to http/2: " + san(jso.vhosts[n].http2_upg) + "
" + - "
Server status
...
"; + "
Mounts
"; var m; for (m = 0; m < jso.vhosts[n].mounts.length; m++) { s = s + "" } s = s + "
MountpointOriginCache Policy
"; s = s + san(jso.vhosts[n].mounts[m].mountpoint) + "" + - san(jso.vhosts[n].mounts[m].origin); + san(jso.vhosts[n].mounts[m].origin) + + ""; + if (parseInt(san(jso.vhosts[n].mounts[m].cache_max_age))) + s = s + "max-age: " + + san(jso.vhosts[n].mounts[m].cache_max_age) + + ", reuse: " + + san(jso.vhosts[n].mounts[m].cache_reuse) + + ", reval: " + + san(jso.vhosts[n].mounts[m].cache_revalidate) + + ", inter: " + + san(jso.vhosts[n].mounts[m].cache_intermediaries); s = s + "
"; @@ -229,8 +242,7 @@ function get_appropriate_ws_url() } socket_status.onclose = function(){ - document.getElementById("s_statustd").style.backgroundColor = "#ff4040"; - document.getElementById("s_status").textContent = " websocket connection CLOSED "; + document.getElementById("title").innerHTML = "Server Status (Disconnected)"; } } catch(exception) { alert('

Error' + exception);