1
0
Fork 0
mirror of https://libwebsockets.org/repo/libwebsockets synced 2025-03-15 17:24:44 +00:00

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 <andy@warmcat.com>
This commit is contained in:
Andy Green 2016-04-22 08:53:49 +08:00
parent 748a2210bd
commit 42e8b189dc
13 changed files with 303 additions and 137 deletions

View file

@ -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()

View file

@ -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

View file

@ -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)

View file

@ -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];

View file

@ -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\"",

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -8,6 +8,7 @@
"gid": "48",
"interface": "eth0",
"count-threads": "1",
"server-string": "lwsws",
"init-ssl": "yes"
}
}

View file

@ -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"
}]
}
]
}]
}

BIN
plugins/lwsws-logo.png Normal file

Binary file not shown.

After

(image error) Size: 5.1 KiB

View file

@ -98,7 +98,9 @@
<header></header>
<article>
<table><tr><td align=center>
<table>
<tr><td><img src="./lwsws-logo.png"></td><td><span id=title class=title>Server status</span></td></tr>
<tr><td align=center colspan=2>
<div id="conninfo">...</div>
</td></tr>
@ -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 = "<pre>"+msg.data+"</pre>";
@ -210,14 +213,24 @@ function get_appropriate_ws_url()
"total http transactions " + san(jso.vhosts[n].trans) + "<br>" +
"Upgrades to ws: " + san(jso.vhosts[n].ws_upg) + ", " +
"to http/2: " + san(jso.vhosts[n].http2_upg) + "<br>" +
"<table><tr><td class=t colspan=2>Mounts</td></tr>";
"<table><tr><td class=t>Mountpoint</td><td class=t>Origin</td><td class=t>Cache Policy</td></tr>";
var m;
for (m = 0; m < jso.vhosts[n].mounts.length; m++) {
s = s + "<tr><td>";
s = s + san(jso.vhosts[n].mounts[m].mountpoint) +
"</td><td>" +
san(jso.vhosts[n].mounts[m].origin);
san(jso.vhosts[n].mounts[m].origin) +
"</td><td>";
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 + "</td></tr>"
}
s = s + "</table>";
@ -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('<p>Error' + exception);