Make redbean cache directive configurable (#750)

Thank you @johnmuhl for the proposal. Fixes #739
This commit is contained in:
Paul Kulchenko 2023-02-23 22:24:40 -08:00 committed by GitHub
parent db16f0129a
commit 0312898979
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 16 deletions

View file

@ -1419,15 +1419,18 @@ FUNCTIONS
listing page. The brand string needs to be a UTF-8 value that's
encodable as ISO-8859-1. If the brand is changed to something
other than redbean, then the promotional links will be removed
from the listing page too. This function should only be called
from /.init.lua.
from the listing page too.
This function should only be called from /.init.lua.
ProgramCache(seconds:int)
ProgramCache(seconds:int[, directive:string])
Configures Cache-Control and Expires header generation for static
asset serving. A negative value will disable the headers. Zero
means don't cache. Greater than zero asks public proxies and
browsers to cache for a given number of seconds. This should only
be called from /.init.lua.
browsers to cache for a given number of seconds. The directive
value is added to the Cache-Control header when specified (with
"must-revalidate" provided by default) and can be set to an empty
string to remove the default value.
This function should only be called from /.init.lua.
ProgramCertificate(pem:str)
Same as the -C flag if called from .init.lua, e.g.
@ -1458,7 +1461,7 @@ FUNCTIONS
ProgramTimeout(milliseconds:int|seconds:int)
Default timeout is 60000ms. Minimal value of timeout is 10(ms).
Negative values (<0) sets the keepalive in seconds.
This should only be called from /.init.lua.
This function should only be called from /.init.lua.
ProgramPort(uint16)
Hard-codes the port number on which to listen, which can be any
@ -1496,8 +1499,8 @@ FUNCTIONS
Configures fallback routing for paths which would otherwise return
404 Not Found. If code is 0 then the path is rewritten internally
as an accelerated redirect. If code is 301, 302, 307, or 308 then
a redirect response will be sent to the client. This should only
be called from /.init.lua.
a redirect response will be sent to the client.
This function should only be called from /.init.lua.
ProgramSslTicketLifetime(seconds:int)
Defaults to 86400 (24 hours). This may be set to ≤0 to disable

View file

@ -498,6 +498,7 @@ static const char *histpath;
static struct pollfd *polls;
static size_t payloadlength;
static int64_t cacheseconds;
static const char *cachedirective;
static const char *monitortty;
static const char *serverheader;
static struct Strings stagedirs;
@ -1037,8 +1038,9 @@ static void ProgramTimeout(long ms) {
}
}
static void ProgramCache(long x) {
static void ProgramCache(long x, const char *s) {
cacheseconds = x;
if (s) cachedirective = s;
}
static void SetDefaults(void) {
@ -1046,7 +1048,7 @@ static void SetDefaults(void) {
VERSION >> 010, VERSION >> 000)));
__log_level = kLogInfo;
maxpayloadsize = 64 * 1024;
ProgramCache(-1);
ProgramCache(-1, "must-revalidate");
ProgramTimeout(60 * 1000);
ProgramSslTicketLifetime(24 * 60 * 60);
sslfetchverify = true;
@ -2275,14 +2277,15 @@ static char *AppendExpires(char *p, int64_t t) {
return AppendCrlf(p);
}
static char *AppendCache(char *p, int64_t seconds) {
static char *AppendCache(char *p, int64_t seconds, char *directive) {
if (seconds < 0) return p;
p = stpcpy(p, "Cache-Control: max-age=");
p = FormatUint64(p, seconds);
if (!seconds) {
p = stpcpy(p, ", no-store");
} else {
p = stpcpy(p, ", must-revalidate");
} else if (directive && *directive) {
p = stpcpy(p, ", ");
p = stpcpy(p, directive);
}
p = AppendCrlf(p);
return AppendExpires(p, shared->nowish.tv_sec + seconds);
@ -4442,7 +4445,8 @@ static int LuaProgramPort(lua_State *L) {
static int LuaProgramCache(lua_State *L) {
OnlyCallFromMainProcess(L, "ProgramCache");
return LuaProgramInt(L, ProgramCache);
ProgramCache(luaL_checkinteger(L, 1), luaL_optstring(L, 2, NULL));
return 0;
}
static int LuaProgramTimeout(lua_State *L) {
@ -6159,7 +6163,7 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) {
p = AppendHeader(p, "Last-Modified", a->lastmodifiedstr);
if (cpm.msg.version >= 11) {
if (!cpm.gotcachecontrol) {
p = AppendCache(p, cacheseconds);
p = AppendCache(p, cacheseconds, cachedirective);
}
if (!IsCompressed(a)) {
p = stpcpy(p, "Accept-Ranges: bytes\r\n");
@ -7279,7 +7283,11 @@ static void GetOpts(int argc, char *argv[]) {
CASE('G', ProgramGid(atoi(optarg)));
CASE('p', ProgramPort(ParseInt(optarg)));
CASE('R', ProgramRedirectArg(0, optarg));
CASE('c', ProgramCache(ParseInt(optarg)));
case 'c': ; // accept "num" or "num,directive"
char *p;
long ret = strtol(optarg, &p, 0);
ProgramCache(ret, *p ? p+1 : NULL); // skip separator, if any
break;
CASE('r', ProgramRedirectArg(307, optarg));
CASE('t', ProgramTimeout(ParseInt(optarg)));
CASE('h', PrintUsage(1, EXIT_SUCCESS));