Add /statusz page to redbean plus other enhancements

redbean improvements:

- Explicitly disable corking
- Simulate Python regex API for Lua
- Send warmup requests in main process on startup
- Add Class-A granular IPv4 network classification
- Add /statusz page so you can monitor your redbean's health
- Fix regressions on OpenBSD/NetBSD caused by recent changes
- Plug Authorization header into Lua GetUser and GetPass APIs
- Recognize X-Forwarded-{For,Host} from local reverse proxies
- Add many additional functions to redbean Lua server page API
- Report resource usage of child processes on `/` listing page
- Introduce `-a` flag for logging child process resource usage
- Introduce `-t MILLIS` flag and `ProgramTimeout(ms)` init API
- Introduce `-H "Header: value"` flag and `ProgramHeader(k,v)` API

Cosmopolitan Libc improvements:

- Make strerror() simpler
- Make inet_pton() not depend on sscanf()
- Fix OpenExecutable() which broke .data section earlier
- Fix stdio in cases where it overflows kernel tty buffer
- Fix bugs in crash reporting w/o .com.dbg binary present
- Add polyfills for SO_LINGER, SO_RCVTIMEO, and SO_SNDTIMEO
- Polyfill TCP_CORK on BSD and XNU using TCP_NOPUSH magnums

New netcat clone in examples/nc.c:

While testing some of the failure conditions for redbean, I noticed that
BusyBox's `nc` command is pretty busted, if you use it as an interactive
tool, rather than having it be part of a pipeline. Unfortunately this'll
only work on UNIX since Windows doesn't let us poll on stdio and sockets
at the same time because I don't think they want tools like this running
on their platform. So if you want forbidden fruit, it's here so enjoy it
This commit is contained in:
Justine Tunney 2021-04-23 10:45:19 -07:00
parent 4effa23528
commit b107d2709f
163 changed files with 4425 additions and 2104 deletions

View file

@ -18,42 +18,46 @@
*/
#include "libc/str/str.h"
#include "libc/x/x.h"
#include "net/http/http.h"
#include "net/http/escape.h"
/**
* Inserts spaces before lines.
*
* @param data is input value
* @param size if -1 implies strlen
* @param out_size if non-NULL receives output length
* @param amt is number of spaces to use
* @param p is input value
* @param n if -1 implies strlen
* @param z if non-NULL receives output length
* @param j is number of spaces to use
* @return allocated NUL-terminated buffer, or NULL w/ errno
*/
char *IndentLines(const char *data, size_t size, size_t *out_size, size_t amt) {
char *r;
const char *p;
size_t i, n, m, a;
if (size == -1) size = data ? strlen(data) : 0;
char *IndentLines(const char *p, size_t n, size_t *z, size_t j) {
char *r, *q;
const char *l;
size_t i, t, m, a;
if (n == -1) n = p ? strlen(p) : 0;
r = 0;
n = 0;
t = 0;
do {
if ((p = memchr(data, '\n', size))) {
m = p + 1 - data;
a = *data != '\r' && *data != '\n' ? amt : 0;
if ((l = memchr(p, '\n', n))) {
m = l + 1 - p;
a = *p != '\r' && *p != '\n' ? j : 0;
} else {
m = size;
a = size ? amt : 0;
m = n;
a = n ? j : 0;
}
r = xrealloc(r, n + a + m + 1);
memset(r + n, ' ', a);
memcpy(r + n + a, data, m);
n += a + m;
data += m;
size -= m;
} while (p);
if (out_size) {
*out_size = n;
}
r[n] = '\0';
if ((q = realloc(r, t + a + m + 1))) {
r = q;
} else {
free(r);
if (z) *z = 0;
return 0;
}
memset(r + t, ' ', a);
memcpy(r + t + a, p, m);
t += a + m;
p += m;
n -= m;
} while (l);
if (z) *z = t;
r[t] = '\0';
return r;
}