mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 08:20:28 +00:00
Add UUID v7 generation to Redbean
This commit is contained in:
parent
01267ea0f5
commit
bc74d79c89
5 changed files with 308 additions and 143 deletions
|
@ -1981,6 +1981,10 @@ function Underlong(str) end
|
|||
--- @return string
|
||||
function UuidV4() end
|
||||
|
||||
--- Generate a uuid_v7
|
||||
--- @return string
|
||||
function UuidV7() end
|
||||
|
||||
---@param x integer
|
||||
---@return integer # position of first bit set.
|
||||
--- Passing `0` will raise an error. Same as the Intel x86 instruction BSF.
|
||||
|
|
|
@ -1065,6 +1065,9 @@ FUNCTIONS
|
|||
UuidV4() -> str
|
||||
Returns an uuid v4 string.
|
||||
|
||||
UuidV7() -> str
|
||||
Returns an uuid v7 string.
|
||||
|
||||
Fetch(url:str[,body:str|{method=value:str,body=value:str,headers=table,...}])
|
||||
├─→ status:int, {header:str=value:str,...}, body:str
|
||||
└─→ nil, error:str
|
||||
|
@ -1612,7 +1615,7 @@ FUNCTIONS
|
|||
called from `.init.lua`. This function is not available in
|
||||
unsecure mode.
|
||||
|
||||
ProgramSslRequired(mandatory:str)
|
||||
ProgramSslRequired(mandatory:bool)
|
||||
Enables the blocking of HTTP so that all inbound clients and
|
||||
must use the TLS transport layer. This has the same effect as
|
||||
the `-J` flag. Fetch() is still allowed to make outbound HTTP
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "libc/sysv/consts/rusage.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/http/escape.h"
|
||||
#include "net/http/http.h"
|
||||
|
@ -475,7 +475,8 @@ int LuaSlurp(lua_State *L) {
|
|||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
if (!got) break;
|
||||
if (!got)
|
||||
break;
|
||||
luaL_addlstring(&b, tb, got);
|
||||
} else if (errno == EINTR) {
|
||||
errno = olderr;
|
||||
|
@ -617,7 +618,8 @@ dontinline int LuaBase32Impl(lua_State *L,
|
|||
const char *a = luaL_optlstring(L, 2, "", &al);
|
||||
if (!IS2POW(al) || al > 128 || al == 1)
|
||||
return luaL_error(L, "alphabet length is not a power of 2 in range 2..128");
|
||||
if (!(p = B32(s, sl, a, al, &sl))) return luaL_error(L, "out of memory");
|
||||
if (!(p = B32(s, sl, a, al, &sl)))
|
||||
return luaL_error(L, "out of memory");
|
||||
lua_pushlstring(L, p, sl);
|
||||
free(p);
|
||||
return 1;
|
||||
|
@ -693,10 +695,12 @@ int LuaGetCryptoHash(lua_State *L) {
|
|||
const void *p = luaL_checklstring(L, 2, &pl);
|
||||
const void *k = luaL_optlstring(L, 3, "", &kl);
|
||||
const mbedtls_md_info_t *digest = mbedtls_md_info_from_string(h);
|
||||
if (!digest) return luaL_argerror(L, 1, "unknown hash type");
|
||||
if (!digest)
|
||||
return luaL_argerror(L, 1, "unknown hash type");
|
||||
if (kl == 0) {
|
||||
// no key provided, run generic hash function
|
||||
if ((digest->f_md)(p, pl, d)) return luaL_error(L, "bad input data");
|
||||
if ((digest->f_md)(p, pl, d))
|
||||
return luaL_error(L, "bad input data");
|
||||
} else if (mbedtls_md_hmac(digest, k, kl, p, pl, d)) {
|
||||
return luaL_error(L, "bad input data");
|
||||
}
|
||||
|
@ -854,6 +858,22 @@ int LuaUuidV4(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int LuaUuidV7(lua_State *L) {
|
||||
char uuid_str[37] = {0};
|
||||
struct timespec now = timespec_real();
|
||||
uint64_t time_now = timespec_tonanos(now);
|
||||
uint64_t random_data = _rand64();
|
||||
snprintf(uuid_str, sizeof(uuid_str), "%08x-%04x-%04x-%04x-%012llx",
|
||||
(uint32_t)(time_now >> 32), //8
|
||||
(uint16_t)(time_now >> 16), //4
|
||||
(uint16_t)((0x7 << 12) | (time_now >> 4 & 0x0fff)), //4
|
||||
(uint16_t)((0b10 << 14 | ((time_now & 0x000f) << 10)) | (random_data & 0x03FF)), //4
|
||||
(uint64_t)(random_data >> 4 & 0xFFFFFFFFFFFF) //12
|
||||
);
|
||||
lua_pushfstring(L, uuid_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static dontinline int LuaHasherImpl(lua_State *L, size_t k,
|
||||
int H(const void *, size_t, uint8_t *)) {
|
||||
size_t n;
|
||||
|
|
|
@ -91,6 +91,7 @@ int LuaSlurp(lua_State *);
|
|||
int LuaUncompress(lua_State *);
|
||||
int LuaUnderlong(lua_State *);
|
||||
int LuaUuidV4(lua_State *);
|
||||
int LuaUuidV7(lua_State *);
|
||||
int LuaVisualizeControlCodes(lua_State *);
|
||||
|
||||
void LuaPushUrlView(lua_State *, struct UrlView *);
|
||||
|
|
|
@ -644,11 +644,14 @@ static bool ShouldAvoidGzip(void) {
|
|||
static char *MergePaths(const char *p, size_t n, const char *q, size_t m,
|
||||
size_t *z) {
|
||||
char *r;
|
||||
if (n && p[n - 1] == '/') --n;
|
||||
if (m && q[0] == '/') ++q, --m;
|
||||
if (n && p[n - 1] == '/')
|
||||
--n;
|
||||
if (m && q[0] == '/')
|
||||
++q, --m;
|
||||
r = xmalloc(n + 1 + m + 1);
|
||||
mempcpy(mempcpy(mempcpy(mempcpy(r, p, n), "/", 1), q, m), "", 1);
|
||||
if (z) *z = n + 1 + m;
|
||||
if (z)
|
||||
*z = n + 1 + m;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -698,7 +701,8 @@ static void AppendCert(mbedtls_x509_crt *cert, mbedtls_pk_context *key) {
|
|||
static void InternCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) {
|
||||
int r;
|
||||
size_t i;
|
||||
if (cert->next) InternCertificate(cert->next, cert);
|
||||
if (cert->next)
|
||||
InternCertificate(cert->next, cert);
|
||||
if (prev) {
|
||||
if (mbedtls_x509_crt_check_parent(prev, cert, 1)) {
|
||||
DEBUGF("(ssl) unbundling %`'s from %`'s",
|
||||
|
@ -728,18 +732,22 @@ static void InternCertificate(mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) {
|
|||
LogCertificate("loaded certificate", cert);
|
||||
if (!cert->next && !IsSelfSigned(cert) && cert->max_pathlen) {
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (mbedtls_pk_can_do(&cert->pk, certs.p[i].cert->sig_pk) &&
|
||||
!mbedtls_x509_crt_check_parent(cert, certs.p[i].cert, 1) &&
|
||||
!IsSelfSigned(certs.p[i].cert)) {
|
||||
if (ChainCertificate(cert, certs.p[i].cert)) break;
|
||||
if (ChainCertificate(cert, certs.p[i].cert))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IsSelfSigned(cert)) {
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (certs.p[i].cert->next) continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (certs.p[i].cert->next)
|
||||
continue;
|
||||
if (certs.p[i].cert->max_pathlen &&
|
||||
mbedtls_pk_can_do(&certs.p[i].cert->pk, cert->sig_pk) &&
|
||||
!mbedtls_x509_crt_check_parent(certs.p[i].cert, cert, 1)) {
|
||||
|
@ -782,7 +790,8 @@ static void ProgramPrivateKey(const char *p, size_t n) {
|
|||
rc = mbedtls_pk_parse_key(key, waqapi, n + 1, 0, 0);
|
||||
mbedtls_platform_zeroize(waqapi, n);
|
||||
free(waqapi);
|
||||
if (rc != 0) FATALF("(ssl) error: load key (grep -0x%04x)", -rc);
|
||||
if (rc != 0)
|
||||
FATALF("(ssl) error: load key (grep -0x%04x)", -rc);
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (certs.p[i].cert && !certs.p[i].key &&
|
||||
!mbedtls_pk_check_pair(&certs.p[i].cert->pk, key)) {
|
||||
|
@ -811,7 +820,8 @@ static void ProgramPort(long port) {
|
|||
if (!(0 <= port && port <= 65535)) {
|
||||
FATALF("(cfg) error: bad port: %d", port);
|
||||
}
|
||||
if (port == 443) listeningonport443 = true;
|
||||
if (port == 443)
|
||||
listeningonport443 = true;
|
||||
ports.p = realloc(ports.p, ++ports.n * sizeof(*ports.p));
|
||||
ports.p[ports.n - 1] = port;
|
||||
}
|
||||
|
@ -942,13 +952,15 @@ static void DescribeAddress(char buf[40], uint32_t addr, uint16_t port) {
|
|||
|
||||
static inline int GetServerAddr(uint32_t *ip, uint16_t *port) {
|
||||
*ip = ntohl(serveraddr->sin_addr.s_addr);
|
||||
if (port) *port = ntohs(serveraddr->sin_port);
|
||||
if (port)
|
||||
*port = ntohs(serveraddr->sin_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int GetClientAddr(uint32_t *ip, uint16_t *port) {
|
||||
*ip = ntohl(clientaddr.sin_addr.s_addr);
|
||||
if (port) *port = ntohs(clientaddr.sin_port);
|
||||
if (port)
|
||||
*port = ntohs(clientaddr.sin_port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1050,8 @@ static void ProgramTimeout(long ms) {
|
|||
|
||||
static void ProgramCache(long x, const char *s) {
|
||||
cacheseconds = x;
|
||||
if (s) cachedirective = strdup(s);
|
||||
if (s)
|
||||
cachedirective = strdup(s);
|
||||
}
|
||||
|
||||
static void SetDefaults(void) {
|
||||
|
@ -1183,9 +1196,11 @@ static void ChangeUser(void) {
|
|||
}
|
||||
|
||||
static void Daemonize(void) {
|
||||
if (fork() > 0) exit(0);
|
||||
if (fork() > 0)
|
||||
exit(0);
|
||||
setsid();
|
||||
if (fork() > 0) _exit(0);
|
||||
if (fork() > 0)
|
||||
_exit(0);
|
||||
umask(0);
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1224,8 @@ static void LuaEvalCode(const char *code) {
|
|||
// handle `-F PATH` arg
|
||||
static void LuaEvalFile(const char *path) {
|
||||
char *f = gc(xslurp(path, 0));
|
||||
if (!f) FATALF("(cfg) error: failed to read file %`'s", path);
|
||||
if (!f)
|
||||
FATALF("(cfg) error: failed to read file %`'s", path);
|
||||
LuaEvalCode(f);
|
||||
}
|
||||
|
||||
|
@ -1465,8 +1481,10 @@ static ssize_t WritevAll(int fd, struct iovec *iov, int iovlen) {
|
|||
total = 0;
|
||||
do {
|
||||
if (i) {
|
||||
while (i < iovlen && !iov[i].iov_len) ++i;
|
||||
if (i == iovlen) break;
|
||||
while (i < iovlen && !iov[i].iov_len)
|
||||
++i;
|
||||
if (i == iovlen)
|
||||
break;
|
||||
}
|
||||
if ((rc = writev(fd, iov + i, iovlen - i)) != -1) {
|
||||
wrote = rc;
|
||||
|
@ -1501,7 +1519,8 @@ static int TlsFlush(struct TlsBio *bio, const unsigned char *buf, size_t len) {
|
|||
v[1].iov_base = (void *)buf;
|
||||
v[1].iov_len = len;
|
||||
if (WritevAll(bio->fd, v, 2) != -1) {
|
||||
if (bio->c > 0) bio->c = 0;
|
||||
if (bio->c > 0)
|
||||
bio->c = 0;
|
||||
} else if (errno == EINTR) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
|
@ -1526,7 +1545,8 @@ static int TlsSend(void *ctx, const unsigned char *buf, size_t len) {
|
|||
bio->c += len;
|
||||
return len;
|
||||
}
|
||||
if ((rc = TlsFlush(bio, buf, len)) < 0) return rc;
|
||||
if ((rc = TlsFlush(bio, buf, len)) < 0)
|
||||
return rc;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -1534,11 +1554,13 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
int r;
|
||||
struct iovec v[2];
|
||||
struct TlsBio *bio = ctx;
|
||||
if ((r = TlsFlush(bio, 0, 0)) < 0) return r;
|
||||
if ((r = TlsFlush(bio, 0, 0)) < 0)
|
||||
return r;
|
||||
if (bio->a < bio->b) {
|
||||
r = MIN(n, bio->b - bio->a);
|
||||
memcpy(p, bio->t + bio->a, r);
|
||||
if ((bio->a += r) == bio->b) bio->a = bio->b = 0;
|
||||
if ((bio->a += r) == bio->b)
|
||||
bio->a = bio->b = 0;
|
||||
return r;
|
||||
}
|
||||
v[0].iov_base = p;
|
||||
|
@ -1559,7 +1581,8 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
}
|
||||
if (r > n) bio->b = r - n;
|
||||
if (r > n)
|
||||
bio->b = r - n;
|
||||
return MIN(n, r);
|
||||
}
|
||||
|
||||
|
@ -1655,11 +1678,15 @@ static void NotifyClose(void) {
|
|||
|
||||
static void WipeSigningKeys(void) {
|
||||
size_t i;
|
||||
if (uniprocess) return;
|
||||
if (uniprocess)
|
||||
return;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].key) continue;
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert->ca_istrue) continue;
|
||||
if (!certs.p[i].key)
|
||||
continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (!certs.p[i].cert->ca_istrue)
|
||||
continue;
|
||||
mbedtls_pk_free(certs.p[i].key);
|
||||
Free(&certs.p[i].key);
|
||||
}
|
||||
|
@ -1695,7 +1722,8 @@ static void CertsDestroy(void) {
|
|||
}
|
||||
|
||||
static void WipeServingKeys(void) {
|
||||
if (uniprocess) return;
|
||||
if (uniprocess)
|
||||
return;
|
||||
mbedtls_ssl_ticket_free(&ssltick);
|
||||
mbedtls_ssl_key_cert_free(conf.key_cert), conf.key_cert = 0;
|
||||
CertsDestroy();
|
||||
|
@ -1897,13 +1925,15 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
//
|
||||
for (int i = 0; i < ips.n; ++i) {
|
||||
uint32_t ip = ips.p[i];
|
||||
if (IsLoopbackIp(ip)) continue;
|
||||
if (IsLoopbackIp(ip))
|
||||
continue;
|
||||
char rname[NI_MAXHOST];
|
||||
struct sockaddr_in addr4 = {AF_INET, 0, {htonl(ip)}};
|
||||
if (getnameinfo((struct sockaddr *)&addr4, sizeof(addr4), rname,
|
||||
sizeof(rname), 0, 0, NI_NAMEREQD) == 0) {
|
||||
char *s = gc(strdup(rname));
|
||||
if (!name) name = s;
|
||||
if (!name)
|
||||
name = s;
|
||||
bool isduplicate = false;
|
||||
for (int j = 0; j < nsan; ++j) {
|
||||
if (san[j].tag == MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
|
@ -1925,7 +1955,8 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
// add san entry to cert for each ip address owned by system
|
||||
for (int i = 0; i < ips.n; ++i) {
|
||||
uint32_t ip = ips.p[i];
|
||||
if (IsLoopbackIp(ip)) continue;
|
||||
if (IsLoopbackIp(ip))
|
||||
continue;
|
||||
san = realloc(san, ++nsan * sizeof(*san));
|
||||
san[nsan - 1].tag = MBEDTLS_X509_SAN_IP_ADDRESS;
|
||||
san[nsan - 1].ip4 = ip;
|
||||
|
@ -1974,9 +2005,12 @@ static void ConfigureCertificate(mbedtls_x509write_cert *cw, struct Cert *ca,
|
|||
static struct Cert GetKeySigningKey(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].key) continue;
|
||||
if (!certs.p[i].cert) continue;
|
||||
if (!certs.p[i].cert->ca_istrue) continue;
|
||||
if (!certs.p[i].key)
|
||||
continue;
|
||||
if (!certs.p[i].cert)
|
||||
continue;
|
||||
if (!certs.p[i].cert->ca_istrue)
|
||||
continue;
|
||||
if (mbedtls_x509_crt_check_key_usage(certs.p[i].cert,
|
||||
MBEDTLS_X509_KU_KEY_CERT_SIGN)) {
|
||||
continue;
|
||||
|
@ -2059,7 +2093,8 @@ static void LoadCertificates(void) {
|
|||
}
|
||||
#ifdef MBEDTLS_ECP_C
|
||||
ecp = GenerateEcpCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &ecp, "server");
|
||||
if (!havecert)
|
||||
UseCertificate(&conf, &ecp, "server");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &ecp, "client");
|
||||
}
|
||||
|
@ -2068,7 +2103,8 @@ static void LoadCertificates(void) {
|
|||
#ifdef MBEDTLS_RSA_C
|
||||
if (!norsagen) {
|
||||
rsa = GenerateRsaCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &rsa, "server");
|
||||
if (!havecert)
|
||||
UseCertificate(&conf, &rsa, "server");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &rsa, "client");
|
||||
}
|
||||
|
@ -2237,11 +2273,13 @@ static bool OpenZip(bool force) {
|
|||
|
||||
static struct Asset *GetAssetZip(const char *path, size_t pathlen) {
|
||||
uint32_t i, step, hash;
|
||||
if (pathlen > 1 && path[0] == '/') ++path, --pathlen;
|
||||
if (pathlen > 1 && path[0] == '/')
|
||||
++path, --pathlen;
|
||||
hash = Hash(path, pathlen);
|
||||
for (step = 0;; ++step) {
|
||||
i = (hash + ((step * (step + 1)) >> 1)) & (assets.n - 1);
|
||||
if (!assets.p[i].hash) return NULL;
|
||||
if (!assets.p[i].hash)
|
||||
return NULL;
|
||||
if (hash == assets.p[i].hash &&
|
||||
pathlen == ZIP_CFILE_NAMESIZE(zmap + assets.p[i].cf) &&
|
||||
memcmp(path, ZIP_CFILE_NAME(zmap + assets.p[i].cf), pathlen) == 0) {
|
||||
|
@ -2288,7 +2326,8 @@ static struct Asset *GetAsset(const char *path, size_t pathlen) {
|
|||
}
|
||||
|
||||
static char *AppendHeader(char *p, const char *k, const char *v) {
|
||||
if (!v) return p;
|
||||
if (!v)
|
||||
return p;
|
||||
return AppendCrlf(stpcpy(stpcpy(stpcpy(p, k), ": "), v));
|
||||
}
|
||||
|
||||
|
@ -2316,7 +2355,8 @@ static char *AppendExpires(char *p, int64_t t) {
|
|||
}
|
||||
|
||||
static char *AppendCache(char *p, int64_t seconds, char *directive) {
|
||||
if (seconds < 0) return p;
|
||||
if (seconds < 0)
|
||||
return p;
|
||||
p = stpcpy(p, "Cache-Control: max-age=");
|
||||
p = FormatUint64(p, seconds);
|
||||
if (!seconds) {
|
||||
|
@ -2392,7 +2432,8 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
|||
}
|
||||
if (!a->file) {
|
||||
size = GetZipLfileUncompressedSize(zmap + a->lf);
|
||||
if (size == SIZE_MAX || !(data = malloc(size + 1))) return NULL;
|
||||
if (size == SIZE_MAX || !(data = malloc(size + 1)))
|
||||
return NULL;
|
||||
if (IsCompressed(a)) {
|
||||
if (!Inflate(data, size, ZIP_LFILE_CONTENT(zmap + a->lf),
|
||||
GetZipCfileCompressedSize(zmap + a->cf))) {
|
||||
|
@ -2407,7 +2448,8 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
|||
return NULL;
|
||||
}
|
||||
data[size] = '\0';
|
||||
if (out_size) *out_size = size;
|
||||
if (out_size)
|
||||
*out_size = size;
|
||||
return data;
|
||||
} else {
|
||||
LockInc(&shared->c.slurps);
|
||||
|
@ -2622,7 +2664,8 @@ static ssize_t YieldGenerator(struct iovec v[3]) {
|
|||
int nresults, status;
|
||||
if (cpm.isyielding > 1) {
|
||||
do {
|
||||
if (!YL || lua_status(YL) != LUA_YIELD) return 0; // done yielding
|
||||
if (!YL || lua_status(YL) != LUA_YIELD)
|
||||
return 0; // done yielding
|
||||
cpm.contentlength = 0;
|
||||
status = lua_resume(YL, NULL, 0, &nresults);
|
||||
if (status != LUA_OK && status != LUA_YIELD) {
|
||||
|
@ -2631,7 +2674,8 @@ static ssize_t YieldGenerator(struct iovec v[3]) {
|
|||
return -1;
|
||||
}
|
||||
lua_pop(YL, nresults);
|
||||
if (!cpm.contentlength) UseOutput();
|
||||
if (!cpm.contentlength)
|
||||
UseOutput();
|
||||
// continue yielding if nothing to return to keep generator running
|
||||
} while (!cpm.contentlength);
|
||||
}
|
||||
|
@ -2667,7 +2711,8 @@ static int LuaCallWithYield(lua_State *L) {
|
|||
CHECK_GT(lua_gettop(L), 0); // make sure that coroutine is anchored
|
||||
YL = co;
|
||||
cpm.generator = YieldGenerator;
|
||||
if (!cpm.isyielding) cpm.isyielding = 1;
|
||||
if (!cpm.isyielding)
|
||||
cpm.isyielding = 1;
|
||||
status = LUA_OK;
|
||||
}
|
||||
return status;
|
||||
|
@ -2770,7 +2815,8 @@ static ssize_t InflateGenerator(struct iovec v[3]) {
|
|||
dg.s.next_out = dg.b;
|
||||
dg.s.avail_out = dg.z;
|
||||
rc = inflate(&dg.s, Z_NO_FLUSH);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) DIEF("(zip) inflate()→%d", rc);
|
||||
if (rc != Z_OK && rc != Z_STREAM_END)
|
||||
DIEF("(zip) inflate()→%d", rc);
|
||||
no = dg.z - dg.s.avail_out;
|
||||
if (no) {
|
||||
v[i].iov_base = dg.b;
|
||||
|
@ -2877,7 +2923,8 @@ static char *GetAssetPath(uint8_t *zcf, size_t *out_size) {
|
|||
p2[0] = '/';
|
||||
memcpy(p2 + 1, p1, n1);
|
||||
p2[1 + n1] = '\0';
|
||||
if (out_size) *out_size = 1 + n1;
|
||||
if (out_size)
|
||||
*out_size = 1 + n1;
|
||||
return p2;
|
||||
}
|
||||
|
||||
|
@ -2928,8 +2975,10 @@ static void LaunchBrowser(const char *path) {
|
|||
port = ntohs(servers.p[0].addr.sin_port);
|
||||
}
|
||||
// assign a loopback address if no server or unknown server address
|
||||
if (!servers.n || !addr.s_addr) addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (*path != '/') path = gc(xasprintf("/%s", path));
|
||||
if (!servers.n || !addr.s_addr)
|
||||
addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
if (*path != '/')
|
||||
path = gc(xasprintf("/%s", path));
|
||||
launch_browser(gc(xasprintf("http://%s:%d%s", inet_ntoa(addr), port, path)));
|
||||
}
|
||||
|
||||
|
@ -3102,11 +3151,13 @@ static const char *MergeNames(const char *a, const char *b) {
|
|||
}
|
||||
|
||||
static void AppendLong1(const char *a, long x) {
|
||||
if (x) appendf(&cpm.outbuf, "%s: %ld\r\n", a, x);
|
||||
if (x)
|
||||
appendf(&cpm.outbuf, "%s: %ld\r\n", a, x);
|
||||
}
|
||||
|
||||
static void AppendLong2(const char *a, const char *b, long x) {
|
||||
if (x) appendf(&cpm.outbuf, "%s.%s: %ld\r\n", a, b, x);
|
||||
if (x)
|
||||
appendf(&cpm.outbuf, "%s.%s: %ld\r\n", a, b, x);
|
||||
}
|
||||
|
||||
static void AppendTimeval(const char *a, struct timeval *tv) {
|
||||
|
@ -3282,7 +3333,8 @@ static char *HandleRedirect(struct Redirect *r) {
|
|||
} else {
|
||||
LockInc(&shared->c.redirects);
|
||||
code = r->code;
|
||||
if (!code) code = 307;
|
||||
if (!code)
|
||||
code = 307;
|
||||
DEBUGF("(rsp) %d redirect to %`'s", code, r->location.s);
|
||||
return AppendHeader(
|
||||
SetStatus(code, GetHttpReason(code)), "Location",
|
||||
|
@ -3629,8 +3681,10 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
|
|||
}
|
||||
INFOF("(srvr) storing asset %`'s", path);
|
||||
disk = gflags = iattrs = 0;
|
||||
if (isutf8(path, pathlen)) gflags |= kZipGflagUtf8;
|
||||
if (istext(data, datalen)) iattrs |= kZipIattrText;
|
||||
if (isutf8(path, pathlen))
|
||||
gflags |= kZipGflagUtf8;
|
||||
if (istext(data, datalen))
|
||||
iattrs |= kZipIattrText;
|
||||
crc = crc32_z(0, data, datalen);
|
||||
if (datalen < 100) {
|
||||
method = kZipCompressionNone;
|
||||
|
@ -3661,9 +3715,12 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
|
|||
OpenZip(false);
|
||||
now = timespec_real();
|
||||
a = GetAssetZip(path, pathlen);
|
||||
if (!mode) mode = a ? GetMode(a) : 0644;
|
||||
if (!(mode & S_IFMT)) mode |= S_IFREG;
|
||||
if (pathlen > 1 && path[0] == '/') ++path, --pathlen;
|
||||
if (!mode)
|
||||
mode = a ? GetMode(a) : 0644;
|
||||
if (!(mode & S_IFMT))
|
||||
mode |= S_IFREG;
|
||||
if (pathlen > 1 && path[0] == '/')
|
||||
++path, --pathlen;
|
||||
dosmode = !(mode & 0200) ? kNtFileAttributeReadonly : 0;
|
||||
ft = (now.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS;
|
||||
GetDosLocalTime(now.tv_sec, &mtime, &mdate);
|
||||
|
@ -3812,12 +3869,14 @@ static void StoreFile(const char *path) {
|
|||
struct stat st;
|
||||
size_t plen, tlen;
|
||||
const char *target = path;
|
||||
if (startswith(target, "./")) target += 2;
|
||||
if (startswith(target, "./"))
|
||||
target += 2;
|
||||
tlen = strlen(target);
|
||||
if (!IsReasonablePath(target, tlen))
|
||||
FATALF("(cfg) error: can't store %`'s: contains '.' or '..' segments",
|
||||
target);
|
||||
if (lstat(path, &st) == -1) FATALF("(cfg) error: can't stat %`'s: %m", path);
|
||||
if (lstat(path, &st) == -1)
|
||||
FATALF("(cfg) error: can't stat %`'s: %m", path);
|
||||
if (!(p = xslurp(path, &plen)))
|
||||
FATALF("(cfg) error: can't read %`'s: %m", path);
|
||||
StoreAsset(target, tlen, p, plen, st.st_mode & 0777);
|
||||
|
@ -3831,10 +3890,13 @@ static void StorePath(const char *dirpath) {
|
|||
if (!isdirectory(dirpath) && !endswith(dirpath, "/")) {
|
||||
return StoreFile(dirpath);
|
||||
}
|
||||
if (!(d = opendir(dirpath))) FATALF("(cfg) error: can't open %`'s", dirpath);
|
||||
if (!(d = opendir(dirpath)))
|
||||
FATALF("(cfg) error: can't open %`'s", dirpath);
|
||||
while ((e = readdir(d))) {
|
||||
if (strcmp(e->d_name, ".") == 0) continue;
|
||||
if (strcmp(e->d_name, "..") == 0) continue;
|
||||
if (strcmp(e->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp(e->d_name, "..") == 0)
|
||||
continue;
|
||||
path = gc(xjoinpaths(dirpath, e->d_name));
|
||||
if (e->d_type == DT_DIR) {
|
||||
StorePath(path);
|
||||
|
@ -3861,7 +3923,8 @@ static int LuaStoreAsset(lua_State *L) {
|
|||
|
||||
static void ReseedRng(mbedtls_ctr_drbg_context *r, const char *s) {
|
||||
#ifndef UNSECURE
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
CHECK_EQ(0, mbedtls_ctr_drbg_reseed(r, (void *)s, strlen(s)));
|
||||
#endif
|
||||
}
|
||||
|
@ -3869,8 +3932,10 @@ static void ReseedRng(mbedtls_ctr_drbg_context *r, const char *s) {
|
|||
static void LogMessage(const char *d, const char *s, size_t n) {
|
||||
size_t n2, n3;
|
||||
char *s2, *s3;
|
||||
if (!LOGGABLE(kLogInfo)) return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||
if (!LOGGABLE(kLogInfo))
|
||||
return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n'))
|
||||
--n;
|
||||
if ((s2 = DecodeLatin1(s, n, &n2))) {
|
||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||
INFOF("(stat) %s %,ld byte message\r\n%.*s", d, n, n3, s3);
|
||||
|
@ -3883,9 +3948,12 @@ static void LogMessage(const char *d, const char *s, size_t n) {
|
|||
static void LogBody(const char *d, const char *s, size_t n) {
|
||||
char *s2, *s3;
|
||||
size_t n2, n3;
|
||||
if (!n) return;
|
||||
if (!LOGGABLE(kLogInfo)) return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n')) --n;
|
||||
if (!n)
|
||||
return;
|
||||
if (!LOGGABLE(kLogInfo))
|
||||
return;
|
||||
while (n && (s[n - 1] == '\r' || s[n - 1] == '\n'))
|
||||
--n;
|
||||
if ((s2 = VisualizeControlCodes(s, n, &n2))) {
|
||||
if ((s3 = IndentLines(s2, n2, &n3, 1))) {
|
||||
INFOF("(stat) %s %,ld byte payload\r\n%.*s", d, n, n3, s3);
|
||||
|
@ -4107,7 +4175,8 @@ static int LuaGetUser(lua_State *L) {
|
|||
if (url.user.p) {
|
||||
LuaPushUrlView(L, &url.user);
|
||||
} else if ((p = gc(GetBasicAuthorization(&n)))) {
|
||||
if (!(q = memchr(p, ':', n))) q = p + n;
|
||||
if (!(q = memchr(p, ':', n)))
|
||||
q = p + n;
|
||||
lua_pushlstring(L, p, q - p);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
|
@ -4148,8 +4217,10 @@ static int LuaGetHost(lua_State *L) {
|
|||
static int LuaGetPort(lua_State *L) {
|
||||
int i, x = 0;
|
||||
OnlyCallDuringRequest(L, "GetPort");
|
||||
for (i = 0; i < url.port.n; ++i) x = url.port.p[i] - '0' + x * 10;
|
||||
if (!x) x = ntohs(serveraddr->sin_port);
|
||||
for (i = 0; i < url.port.n; ++i)
|
||||
x = url.port.p[i] - '0' + x * 10;
|
||||
if (!x)
|
||||
x = ntohs(serveraddr->sin_port);
|
||||
lua_pushinteger(L, x);
|
||||
return 1;
|
||||
}
|
||||
|
@ -4219,7 +4290,8 @@ static int LuaSetHeader(lua_State *L) {
|
|||
OnlyCallDuringRequest(L, "SetHeader");
|
||||
key = luaL_checklstring(L, 1, &keylen);
|
||||
val = luaL_optlstring(L, 2, 0, &vallen);
|
||||
if (!val) return 0;
|
||||
if (!val)
|
||||
return 0;
|
||||
if ((h = GetHttpHeader(key, keylen)) == -1) {
|
||||
if (!IsValidHttpToken(key, keylen)) {
|
||||
luaL_argerror(L, 1, "invalid");
|
||||
|
@ -4283,7 +4355,8 @@ static int LuaGetCookie(lua_State *L) {
|
|||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
if (cookie) free(cookie);
|
||||
if (cookie)
|
||||
free(cookie);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4503,7 +4576,8 @@ static int LuaProgramUniprocess(lua_State *L) {
|
|||
return luaL_argerror(L, 1, "invalid uniprocess mode; boolean expected");
|
||||
}
|
||||
lua_pushboolean(L, uniprocess);
|
||||
if (lua_isboolean(L, 1)) uniprocess = lua_toboolean(L, 1);
|
||||
if (lua_isboolean(L, 1))
|
||||
uniprocess = lua_toboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4525,7 +4599,8 @@ static int LuaProgramMaxWorkers(lua_State *L) {
|
|||
return luaL_argerror(L, 1, "invalid number of workers; integer expected");
|
||||
}
|
||||
lua_pushinteger(L, maxworkers);
|
||||
if (lua_isinteger(L, 1)) maxworkers = lua_tointeger(L, 1);
|
||||
if (lua_isinteger(L, 1))
|
||||
maxworkers = lua_tointeger(L, 1);
|
||||
maxworkers = MAX(maxworkers, 1);
|
||||
return 1;
|
||||
}
|
||||
|
@ -4803,7 +4878,8 @@ static int LuaIsAssetCompressed(lua_State *L) {
|
|||
|
||||
static bool Blackhole(uint32_t ip) {
|
||||
char buf[4];
|
||||
if (blackhole.fd <= 0) return false;
|
||||
if (blackhole.fd <= 0)
|
||||
return false;
|
||||
WRITE32BE(buf, ip);
|
||||
if (sendto(blackhole.fd, &buf, 4, 0, (struct sockaddr *)&blackhole.addr,
|
||||
sizeof(blackhole.addr)) != -1) {
|
||||
|
@ -4927,8 +5003,10 @@ static int LuaProgramTokenBucket(lua_State *L) {
|
|||
reject, //
|
||||
ignore, //
|
||||
ban);
|
||||
if (ignore == -1) ignore = -128;
|
||||
if (ban == -1) ban = -128;
|
||||
if (ignore == -1)
|
||||
ignore = -128;
|
||||
if (ban == -1)
|
||||
ban = -128;
|
||||
if (ban >= 0 && (IsLinux() || IsBsd())) {
|
||||
uint32_t testip = 0;
|
||||
blackhole.addr.sun_family = AF_UNIX;
|
||||
|
@ -4955,14 +5033,16 @@ static int LuaProgramTokenBucket(lua_State *L) {
|
|||
tokenbucket.replenish = timespec_fromnanos(1 / replenish * 1e9);
|
||||
int pid = fork();
|
||||
npassert(pid != -1);
|
||||
if (!pid) Replenisher();
|
||||
if (!pid)
|
||||
Replenisher();
|
||||
++shared->workers;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *GetContentTypeExt(const char *path, size_t n) {
|
||||
const char *r = NULL, *e;
|
||||
if ((r = FindContentType(path, n))) return r;
|
||||
if ((r = FindContentType(path, n)))
|
||||
return r;
|
||||
#ifndef STATIC
|
||||
int top;
|
||||
lua_State *L = GL;
|
||||
|
@ -5053,7 +5133,8 @@ static bool LuaRunAsset(const char *path, bool mandatory) {
|
|||
if (status != LUA_OK || LuaCallWithTrace(L, 0, 0, NULL) != LUA_OK) {
|
||||
LogLuaError("lua code", lua_tostring(L, -1));
|
||||
lua_pop(L, 1); // pop error
|
||||
if (mandatory) exit(1);
|
||||
if (mandatory)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5288,6 +5369,7 @@ static const luaL_Reg kLuaFuncs[] = {
|
|||
{"Uncompress", LuaUncompress}, //
|
||||
{"Underlong", LuaUnderlong}, //
|
||||
{"UuidV4", LuaUuidV4}, //
|
||||
{"UuidV7", LuaUuidV7}, //
|
||||
{"VisualizeControlCodes", LuaVisualizeControlCodes}, //
|
||||
{"Write", LuaWrite}, //
|
||||
{"bin", LuaBin}, //
|
||||
|
@ -5416,7 +5498,8 @@ static void LuaPrint(lua_State *L) {
|
|||
n = lua_gettop(L);
|
||||
if (n > 0) {
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (i > 1) appendw(&b, '\t');
|
||||
if (i > 1)
|
||||
appendw(&b, '\t');
|
||||
struct EncoderConfig conf = {
|
||||
.maxdepth = 64,
|
||||
.sorted = true,
|
||||
|
@ -5450,12 +5533,14 @@ static int LuaInterpreter(lua_State *L) {
|
|||
const char *script;
|
||||
if (optind < __argc) {
|
||||
script = __argv[optind];
|
||||
if (!strcmp(script, "-")) script = 0;
|
||||
if (!strcmp(script, "-"))
|
||||
script = 0;
|
||||
if ((status = luaL_loadfile(L, script)) == LUA_OK) {
|
||||
lua_getglobal(L, "arg");
|
||||
n = luaL_len(L, -1);
|
||||
luaL_checkstack(L, n + 3, "too many script args");
|
||||
for (i = 1; i <= n; i++) lua_rawgeti(L, -i, i);
|
||||
for (i = 1; i <= n; i++)
|
||||
lua_rawgeti(L, -i, i);
|
||||
lua_remove(L, -i); // remove arg table from stack
|
||||
TRACE_BEGIN;
|
||||
status = lua_runchunk(L, n, LUA_MULTRET);
|
||||
|
@ -5469,7 +5554,8 @@ static int LuaInterpreter(lua_State *L) {
|
|||
EnableRawMode();
|
||||
for (;;) {
|
||||
status = lua_loadline(L);
|
||||
if (status == -1) break; // eof
|
||||
if (status == -1)
|
||||
break; // eof
|
||||
if (status == -2) {
|
||||
if (errno == EINTR) {
|
||||
if ((sig = linenoiseGetInterrupt())) {
|
||||
|
@ -5579,10 +5665,14 @@ static void LuaOnServerReload(bool reindex) {
|
|||
}
|
||||
|
||||
static const char *DescribeClose(void) {
|
||||
if (killed) return "killed";
|
||||
if (meltdown) return "meltdown";
|
||||
if (terminated) return "terminated";
|
||||
if (connectionclose) return "connection closed";
|
||||
if (killed)
|
||||
return "killed";
|
||||
if (meltdown)
|
||||
return "meltdown";
|
||||
if (terminated)
|
||||
return "terminated";
|
||||
if (connectionclose)
|
||||
return "connection closed";
|
||||
return "destroyed";
|
||||
}
|
||||
|
||||
|
@ -5859,7 +5949,8 @@ static char *ReadMore(void) {
|
|||
ssize_t rc;
|
||||
LockInc(&shared->c.frags);
|
||||
if ((rc = reader(client, inbuf.p + amtread, inbuf.n - amtread)) != -1) {
|
||||
if (!(got = rc)) return HandlePayloadDisconnect();
|
||||
if (!(got = rc))
|
||||
return HandlePayloadDisconnect();
|
||||
amtread += got;
|
||||
} else if (errno == EINTR) {
|
||||
LockInc(&shared->c.readinterrupts);
|
||||
|
@ -5877,10 +5968,12 @@ static char *ReadMore(void) {
|
|||
static char *SynchronizeLength(void) {
|
||||
char *p;
|
||||
if (hdrsize + payloadlength > amtread) {
|
||||
if (hdrsize + payloadlength > inbuf.n) return HandleHugePayload();
|
||||
if (hdrsize + payloadlength > inbuf.n)
|
||||
return HandleHugePayload();
|
||||
SendContinueIfNeeded();
|
||||
while (amtread < hdrsize + payloadlength) {
|
||||
if ((p = ReadMore())) return p;
|
||||
if ((p = ReadMore()))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
cpm.msgsize = hdrsize + payloadlength;
|
||||
|
@ -5894,9 +5987,11 @@ static char *SynchronizeChunked(void) {
|
|||
SendContinueIfNeeded();
|
||||
while (!(transferlength = Unchunk(&u, inbuf.p + hdrsize, amtread - hdrsize,
|
||||
&payloadlength))) {
|
||||
if ((p = ReadMore())) return p;
|
||||
if ((p = ReadMore()))
|
||||
return p;
|
||||
}
|
||||
if (transferlength == -1) return HandleHugePayload();
|
||||
if (transferlength == -1)
|
||||
return HandleHugePayload();
|
||||
cpm.msgsize = hdrsize + transferlength;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5987,8 +6082,10 @@ static char *HandleRequest(void) {
|
|||
} else {
|
||||
return HandleVersionNotSupported();
|
||||
}
|
||||
if ((p = SynchronizeStream())) return p;
|
||||
if (logbodies) LogBody("received", inbuf.p + hdrsize, payloadlength);
|
||||
if ((p = SynchronizeStream()))
|
||||
return p;
|
||||
if (logbodies)
|
||||
LogBody("received", inbuf.p + hdrsize, payloadlength);
|
||||
if (cpm.msg.version < 11 || HeaderEqualCase(kHttpConnection, "close")) {
|
||||
connectionclose = true;
|
||||
}
|
||||
|
@ -6025,7 +6122,8 @@ static char *HandleRequest(void) {
|
|||
}
|
||||
FreeLater(url.params.p);
|
||||
#ifndef STATIC
|
||||
if (hasonhttprequest) return LuaOnHttpRequest();
|
||||
if (hasonhttprequest)
|
||||
return LuaOnHttpRequest();
|
||||
#endif
|
||||
return Route(url.host.p, url.host.n, url.path.p, url.path.n);
|
||||
}
|
||||
|
@ -6041,7 +6139,8 @@ static char *Route(const char *host, size_t hostlen, const char *path,
|
|||
return p;
|
||||
}
|
||||
if (SlicesEqual(path, pathlen, "/", 1)) {
|
||||
if ((p = ServeIndex("/", 1))) return p;
|
||||
if ((p = ServeIndex("/", 1)))
|
||||
return p;
|
||||
return ServeListing();
|
||||
} else if ((p = RoutePath(path, pathlen))) {
|
||||
return p;
|
||||
|
@ -6090,16 +6189,19 @@ static char *RouteHost(const char *host, size_t hostlen, const char *path,
|
|||
hp = hm <= sizeof(b) ? b : FreeLater(xmalloc(hm));
|
||||
hp[0] = '/';
|
||||
mempcpy(mempcpy(hp + 1, host, hostlen), path, pathlen);
|
||||
if ((p = RoutePath(hp, hn))) return p;
|
||||
if ((p = RoutePath(hp, hn)))
|
||||
return p;
|
||||
if (!isdigit(host[0])) {
|
||||
if (hostlen > 4 &&
|
||||
READ32LE(host) == ('w' | 'w' << 8 | 'w' << 16 | '.' << 24)) {
|
||||
mempcpy(mempcpy(hp + 1, host + 4, hostlen - 4), path, pathlen);
|
||||
if ((p = RoutePath(hp, hn - 4))) return p;
|
||||
if ((p = RoutePath(hp, hn - 4)))
|
||||
return p;
|
||||
} else {
|
||||
mempcpy(mempcpy(mempcpy(hp + 1, "www.", 4), host, hostlen), path,
|
||||
pathlen);
|
||||
if ((p = RoutePath(hp, hn + 4))) return p;
|
||||
if ((p = RoutePath(hp, hn + 4)))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6123,7 +6225,8 @@ static inline bool IsLua(struct Asset *a) {
|
|||
static char *HandleAsset(struct Asset *a, const char *path, size_t pathlen) {
|
||||
char *p;
|
||||
#ifndef STATIC
|
||||
if (IsLua(a)) return ServeLua(a, path, pathlen);
|
||||
if (IsLua(a))
|
||||
return ServeLua(a, path, pathlen);
|
||||
#endif
|
||||
if (cpm.msg.method == kHttpGet || cpm.msg.method == kHttpHead) {
|
||||
LockInc(&shared->c.staticrequests);
|
||||
|
@ -6150,8 +6253,10 @@ static const char *GetContentType(struct Asset *a, const char *path, size_t n) {
|
|||
}
|
||||
|
||||
static bool IsNotModified(struct Asset *a) {
|
||||
if (cpm.msg.version < 10) return false;
|
||||
if (!HasHeader(kHttpIfModifiedSince)) return false;
|
||||
if (cpm.msg.version < 10)
|
||||
return false;
|
||||
if (!HasHeader(kHttpIfModifiedSince))
|
||||
return false;
|
||||
return a->lastmodified <=
|
||||
ParseHttpDateTime(HeaderData(kHttpIfModifiedSince),
|
||||
HeaderLength(kHttpIfModifiedSince));
|
||||
|
@ -6217,8 +6322,10 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) {
|
|||
|
||||
static char *SetStatus(unsigned code, const char *reason) {
|
||||
if (cpm.msg.version == 10) {
|
||||
if (code == 307) code = 302;
|
||||
if (code == 308) code = 301;
|
||||
if (code == 307)
|
||||
code = 302;
|
||||
if (code == 308)
|
||||
code = 301;
|
||||
}
|
||||
cpm.statuscode = code;
|
||||
cpm.hascontenttype = false;
|
||||
|
@ -6321,7 +6428,8 @@ static bool StreamResponse(char *p) {
|
|||
iov[3].iov_len = 0;
|
||||
iov[4].iov_base = 0;
|
||||
iov[4].iov_len = 0;
|
||||
if ((rc = cpm.generator(iov + 2)) <= 0) break;
|
||||
if ((rc = cpm.generator(iov + 2)) <= 0)
|
||||
break;
|
||||
if (cpm.msg.version >= 11) {
|
||||
s = chunkbuf;
|
||||
s += uint64toarray_radix16(rc, s);
|
||||
|
@ -6329,7 +6437,8 @@ static bool StreamResponse(char *p) {
|
|||
iov[1].iov_base = chunkbuf;
|
||||
iov[1].iov_len = s - chunkbuf;
|
||||
}
|
||||
if (Send(iov, 6) == -1) break;
|
||||
if (Send(iov, 6) == -1)
|
||||
break;
|
||||
iov[0].iov_base = 0;
|
||||
iov[0].iov_len = 0;
|
||||
}
|
||||
|
@ -6350,8 +6459,9 @@ static bool HandleMessageActual(void) {
|
|||
long reqtime, contime;
|
||||
char *p;
|
||||
struct timespec now;
|
||||
if ((rc = ParseHttpMessage(&cpm.msg, inbuf.p, amtread)) != -1) {
|
||||
if (!rc) return false;
|
||||
if ((rc = ParseHttpMessage(&cpm.msg, inbuf.p, amtread, inbuf.n)) != -1) {
|
||||
if (!rc)
|
||||
return false;
|
||||
hdrsize = rc;
|
||||
if (logmessages) {
|
||||
LogMessage("received", inbuf.p, hdrsize);
|
||||
|
@ -6373,8 +6483,10 @@ static bool HandleMessageActual(void) {
|
|||
}
|
||||
if (cpm.msg.version >= 10) {
|
||||
p = AppendCrlf(stpcpy(stpcpy(p, "Date: "), shared->currentdate));
|
||||
if (!cpm.branded) p = stpcpy(p, serverheader);
|
||||
if (extrahdrs) p = stpcpy(p, extrahdrs);
|
||||
if (!cpm.branded)
|
||||
p = stpcpy(p, serverheader);
|
||||
if (extrahdrs)
|
||||
p = stpcpy(p, extrahdrs);
|
||||
if (connectionclose) {
|
||||
p = stpcpy(p, "Connection: close\r\n");
|
||||
} else if (timeout.tv_sec < 0 && cpm.msg.version >= 11) {
|
||||
|
@ -6395,7 +6507,8 @@ static bool HandleMessageActual(void) {
|
|||
now = timespec_real();
|
||||
reqtime = timespec_tomicros(timespec_sub(now, startrequest));
|
||||
contime = timespec_tomicros(timespec_sub(now, startconnection));
|
||||
if (hasonloglatency) LuaOnLogLatency(reqtime, contime);
|
||||
if (hasonloglatency)
|
||||
LuaOnLogLatency(reqtime, contime);
|
||||
if (loglatency || LOGGABLE(kLogDebug))
|
||||
LOGF(kLogDebug, "(stat) %`'.*s latency r: %,ldµs c: %,ldµs",
|
||||
cpm.msg.uri.b - cpm.msg.uri.a, inbuf.p + cpm.msg.uri.a, reqtime,
|
||||
|
@ -6422,8 +6535,10 @@ static void InitRequest(void) {
|
|||
}
|
||||
|
||||
static bool IsSsl(unsigned char c) {
|
||||
if (c == 22) return true;
|
||||
if (!(c & 128)) return false;
|
||||
if (c == 22)
|
||||
return true;
|
||||
if (!(c & 128))
|
||||
return false;
|
||||
/* RHEL5 sends SSLv2 hello but supports TLS */
|
||||
DEBUGF("(ssl) %s SSLv2 hello D:", DescribeClient());
|
||||
return true;
|
||||
|
@ -6440,7 +6555,8 @@ static void HandleMessages(void) {
|
|||
for (;;) {
|
||||
if (!cpm.msg.i && amtread) {
|
||||
startrequest = timespec_real();
|
||||
if (HandleMessage()) break;
|
||||
if (HandleMessage())
|
||||
break;
|
||||
}
|
||||
if ((rc = reader(client, inbuf.p + amtread, inbuf.n - amtread)) != -1) {
|
||||
startrequest = timespec_real();
|
||||
|
@ -6483,7 +6599,8 @@ static void HandleMessages(void) {
|
|||
errno = 0;
|
||||
} else if (errno == EAGAIN) {
|
||||
LockInc(&shared->c.readtimeouts);
|
||||
if (amtread) SendTimeout();
|
||||
if (amtread)
|
||||
SendTimeout();
|
||||
NotifyClose();
|
||||
LogClose("read timeout");
|
||||
return;
|
||||
|
@ -6646,7 +6763,8 @@ static void *MemoryMonitor(void *arg) {
|
|||
if (tty != -1) {
|
||||
for (gen = 0, mi = 0, b = 0; !terminatemonitor;) {
|
||||
workers = atomic_load_explicit(&shared->workers, memory_order_relaxed);
|
||||
if (id) id = MAX(1, MIN(id, workers));
|
||||
if (id)
|
||||
id = MAX(1, MIN(id, workers));
|
||||
if (!id && workers) {
|
||||
usleep(50000);
|
||||
continue;
|
||||
|
@ -6931,11 +7049,16 @@ static int HandleConnection(size_t i) {
|
|||
static void MakeExecutableModifiable(void) {
|
||||
#ifdef __x86_64__
|
||||
int ft;
|
||||
if (!(SUPPORT_VECTOR & (_HOSTMETAL | _HOSTWINDOWS | _HOSTXNU))) return;
|
||||
if (IsWindows()) return; // TODO
|
||||
if (IsOpenbsd()) return; // TODO
|
||||
if (IsNetbsd()) return; // TODO
|
||||
if (endswith(zpath, ".dbg")) return;
|
||||
if (!(SUPPORT_VECTOR & (_HOSTMETAL | _HOSTWINDOWS | _HOSTXNU)))
|
||||
return;
|
||||
if (IsWindows())
|
||||
return; // TODO
|
||||
if (IsOpenbsd())
|
||||
return; // TODO
|
||||
if (IsNetbsd())
|
||||
return; // TODO
|
||||
if (endswith(zpath, ".dbg"))
|
||||
return;
|
||||
close(zfd);
|
||||
ft = ftrace_enabled(0);
|
||||
if ((zfd = __open_executable()) == -1) {
|
||||
|
@ -6999,8 +7122,10 @@ static int HandlePoll(int ms) {
|
|||
if (nfds) {
|
||||
// handle pollid/o events
|
||||
for (pollid = 0; pollid < 1 + servers.n; ++pollid) {
|
||||
if (!polls[pollid].revents) continue;
|
||||
if (polls[pollid].fd < 0) continue;
|
||||
if (!polls[pollid].revents)
|
||||
continue;
|
||||
if (polls[pollid].fd < 0)
|
||||
continue;
|
||||
if (polls[pollid].fd) {
|
||||
// handle listen socket
|
||||
lua_repl_lock();
|
||||
|
@ -7011,12 +7136,14 @@ static int HandlePoll(int ms) {
|
|||
rc = HandleConnection(serverid);
|
||||
ishandlingconnection = false;
|
||||
lua_repl_unlock();
|
||||
if (rc == -1) return -1;
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
#ifndef STATIC
|
||||
} else {
|
||||
// handle standard input
|
||||
rc = HandleReadline();
|
||||
if (rc == -1) return rc;
|
||||
if (rc == -1)
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7024,7 +7151,8 @@ static int HandlePoll(int ms) {
|
|||
} else if (__ttyconf.replmode) {
|
||||
// handle refresh repl line
|
||||
rc = HandleReadline();
|
||||
if (rc < 0) return rc;
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
@ -7094,7 +7222,8 @@ static void Listen(void) {
|
|||
}
|
||||
port = ntohs(servers.p[n].addr.sin_port);
|
||||
ip = ntohl(servers.p[n].addr.sin_addr.s_addr);
|
||||
if (ip == INADDR_ANY) ip = INADDR_LOOPBACK;
|
||||
if (ip == INADDR_ANY)
|
||||
ip = INADDR_LOOPBACK;
|
||||
INFOF("(srvr) listen http://%hhu.%hhu.%hhu.%hhu:%d", ip >> 24, ip >> 16,
|
||||
ip >> 8, ip, port);
|
||||
if (printport && !ports.p[j]) {
|
||||
|
@ -7122,7 +7251,8 @@ static void HandleShutdown(void) {
|
|||
CloseServerFds();
|
||||
INFOF("(srvr) received %s", strsignal(shutdownsig));
|
||||
if (shutdownsig != SIGINT && shutdownsig != SIGQUIT) {
|
||||
if (!killed) terminated = false;
|
||||
if (!killed)
|
||||
terminated = false;
|
||||
INFOF("(srvr) killing process group");
|
||||
KillGroup();
|
||||
}
|
||||
|
@ -7193,7 +7323,8 @@ static void SigInit(void) {
|
|||
static void TlsInit(void) {
|
||||
#ifndef UNSECURE
|
||||
int suite;
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
|
||||
if (suiteb && !mbedtls_aes_uses_hardware()) {
|
||||
WARNF("(srvr) requested suiteb crypto, but hardware aes not present");
|
||||
|
@ -7227,7 +7358,8 @@ static void TlsInit(void) {
|
|||
mbedtls_ssl_ticket_parse, &ssltick);
|
||||
}
|
||||
|
||||
if (sslinitialized) return;
|
||||
if (sslinitialized)
|
||||
return;
|
||||
sslinitialized = true;
|
||||
|
||||
LoadCertificates();
|
||||
|
@ -7257,7 +7389,8 @@ static void TlsInit(void) {
|
|||
|
||||
static void TlsDestroy(void) {
|
||||
#ifndef UNSECURE
|
||||
if (unsecure) return;
|
||||
if (unsecure)
|
||||
return;
|
||||
mbedtls_ssl_free(&ssl);
|
||||
mbedtls_ssl_free(&sslcli);
|
||||
mbedtls_ctr_drbg_free(&rng);
|
||||
|
@ -7352,9 +7485,11 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
// if storing asset(s) is requested, don't need to continue
|
||||
if (storeasset) exit(0);
|
||||
if (storeasset)
|
||||
exit(0);
|
||||
// we don't want to drop into a repl after using -e in -i mode
|
||||
if (interpretermode && got_e_arg) exit(0);
|
||||
if (interpretermode && got_e_arg)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void RedBean(int argc, char *argv[]) {
|
||||
|
@ -7362,7 +7497,8 @@ void RedBean(int argc, char *argv[]) {
|
|||
int fd;
|
||||
// don't complain about --assimilate if it's the only parameter,
|
||||
// as it can only get here if it's already native or assimilated
|
||||
if (argc == 2 && strcmp(argv[1], "--assimilate") == 0) return;
|
||||
if (argc == 2 && strcmp(argv[1], "--assimilate") == 0)
|
||||
return;
|
||||
if (IsLinux()) {
|
||||
// disable weird linux capabilities
|
||||
for (int e = errno, i = 0;; ++i) {
|
||||
|
@ -7415,7 +7551,8 @@ void RedBean(int argc, char *argv[]) {
|
|||
shared->workers = 1;
|
||||
}
|
||||
if (daemonize) {
|
||||
if (!logpath) ProgramLogPath("/dev/null");
|
||||
if (!logpath)
|
||||
ProgramLogPath("/dev/null");
|
||||
dup2(2, 1);
|
||||
}
|
||||
SigInit();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue