mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Fix bugs and make improvements to redbean
- Abort if .init.lua fails - Refactor redbean to use new append library - Use first certificate if SNI routing fails - Use function/data sections when building Lua - Don't use self-signed auto-generated cert for client - Add -D staging dirs to redbean lua module default path
This commit is contained in:
parent
55a15c204e
commit
aeeb851422
26 changed files with 703 additions and 513 deletions
|
@ -44,9 +44,10 @@ double MeasureEntropy(const char *p, size_t n) {
|
|||
if (h[i]) {
|
||||
x = h[i];
|
||||
x /= n;
|
||||
e += x * log2(1 / x);
|
||||
e += x * log(x);
|
||||
}
|
||||
}
|
||||
e = -(e / M_LN2);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
|
|
@ -32,16 +32,18 @@ struct MemoryIntervals {
|
|||
} p[128];
|
||||
};
|
||||
|
||||
extern struct MemoryIntervals _mmi;
|
||||
extern hidden struct MemoryIntervals _mmi;
|
||||
|
||||
unsigned FindMemoryInterval(const struct MemoryIntervals *, int) nosideeffect;
|
||||
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect;
|
||||
void PrintMemoryIntervals(int, const struct MemoryIntervals *);
|
||||
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int, int);
|
||||
unsigned FindMemoryInterval(const struct MemoryIntervals *,
|
||||
int) nosideeffect hidden;
|
||||
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
||||
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
||||
int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int,
|
||||
int) hidden;
|
||||
int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int,
|
||||
void (*)(struct MemoryIntervals *, int, int));
|
||||
void ReleaseMemoryNt(struct MemoryIntervals *, int, int);
|
||||
int UntrackMemoryIntervals(void *, size_t);
|
||||
void (*)(struct MemoryIntervals *, int, int)) hidden;
|
||||
void ReleaseMemoryNt(struct MemoryIntervals *, int, int) hidden;
|
||||
int UntrackMemoryIntervals(void *, size_t) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STDIO_APPEND_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_STDIO_APPEND_INTERNAL_H_
|
||||
#ifndef COSMOPOLITAN_LIBC_STDIO_APPEND_H_
|
||||
#define COSMOPOLITAN_LIBC_STDIO_APPEND_H_
|
||||
#include "libc/fmt/pflink.h"
|
||||
|
||||
#define APPEND_COOKIE 21578
|
||||
|
@ -8,22 +8,23 @@
|
|||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct appendz {
|
||||
size_t i; /* data size */
|
||||
size_t n; /* allocation size */
|
||||
size_t i;
|
||||
size_t n;
|
||||
};
|
||||
|
||||
int appendf(char **, const char *, ...);
|
||||
int vappendf(char **, const char *, va_list);
|
||||
int appends(char **, const char *);
|
||||
int appendd(char **, const void *, size_t);
|
||||
int appendw(char **, uint64_t);
|
||||
struct appendz appendz(char *);
|
||||
ssize_t appendr(char **, size_t);
|
||||
ssize_t appendd(char **, const void *, size_t);
|
||||
ssize_t appendw(char **, uint64_t);
|
||||
ssize_t appends(char **, const char *);
|
||||
ssize_t appendf(char **, const char *, ...);
|
||||
ssize_t vappendf(char **, const char *, va_list);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define appendf(BUF, FMT, ...) (appendf)(BUF, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vappendf(BUF, FMT, VA) (vappendf)(BUF, PFLINK(FMT), VA)
|
||||
#define appendf(BUF, FMT, ...) appendf(BUF, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vappendf(BUF, FMT, VA) vappendf(BUF, PFLINK(FMT), VA)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STDIO_APPEND_INTERNAL_H_ */
|
||||
#endif /* COSMOPOLITAN_LIBC_STDIO_APPEND_H_ */
|
||||
|
|
|
@ -26,11 +26,24 @@
|
|||
#define W sizeof(size_t)
|
||||
|
||||
/**
|
||||
* Appends raw data to buffer.
|
||||
* Appends data to buffer, e.g.
|
||||
*
|
||||
* char *b = 0;
|
||||
* appendd(&b, "hello", 5);
|
||||
* free(b);
|
||||
*
|
||||
* The resulting buffer is guaranteed to be NUL-terminated, i.e.
|
||||
* `!b[appendz(b).i]` will be the case.
|
||||
*
|
||||
* @param s may contain nul characters and may be null if `l` is zero
|
||||
* @param l is byte length of `s`
|
||||
* @return bytes appended (always `l`) or -1 if `ENOMEM`
|
||||
* @see appendz(b).i to get buffer length
|
||||
*/
|
||||
int appendd(char **b, const void *s, size_t l) {
|
||||
ssize_t appendd(char **b, const void *s, size_t l) {
|
||||
char *p;
|
||||
struct appendz z;
|
||||
assert(b);
|
||||
z = appendz((p = *b));
|
||||
if (ROUNDUP(z.i + l + 1, 8) + W > z.n) {
|
||||
if (!z.n) z.n = W * 2;
|
||||
|
|
|
@ -19,9 +19,16 @@
|
|||
#include "libc/stdio/append.internal.h"
|
||||
|
||||
/**
|
||||
* Appends formatted data to buffer.
|
||||
* Appends formatted string to buffer, e.g.
|
||||
*
|
||||
* char *b = 0;
|
||||
* appendf(&b, "hello %d\n", 123);
|
||||
* free(b);
|
||||
*
|
||||
* @return bytes appended or -1 if `ENOMEM`
|
||||
* @see appendz(b).i to get buffer length
|
||||
*/
|
||||
int(appendf)(char **b, const char *fmt, ...) {
|
||||
ssize_t(appendf)(char **b, const char *fmt, ...) {
|
||||
int n;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
|
|
71
libc/stdio/appendr.c
Normal file
71
libc/stdio/appendr.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
#define W sizeof(size_t)
|
||||
|
||||
/**
|
||||
* Resets length of append buffer, e.g.
|
||||
*
|
||||
* char *b = 0;
|
||||
* appends(&b, "hello");
|
||||
* appendr(&b, 1);
|
||||
* assert(!strcmp(b, "h"));
|
||||
* appendr(&b, 0);
|
||||
* assert(!strcmp(b, ""));
|
||||
* free(b);
|
||||
*
|
||||
* If `i` is greater than the current length then the extra bytes are
|
||||
* filled with NUL characters.
|
||||
*
|
||||
* The resulting buffer is guarranteed to be NUL-terminated, i.e.
|
||||
* `!b[appendz(b).i]` will be the case.
|
||||
*
|
||||
* @return `i` or -1 if `ENOMEM`
|
||||
* @see appendz(b).i to get buffer length
|
||||
*/
|
||||
ssize_t appendr(char **b, size_t i) {
|
||||
char *p;
|
||||
struct appendz z;
|
||||
assert(b);
|
||||
z = appendz((p = *b));
|
||||
z.n = ROUNDUP(i + 1, 8) + W;
|
||||
if ((p = realloc(p, z.n))) {
|
||||
z.n = malloc_usable_size(p);
|
||||
assert(!(z.n & (W - 1)));
|
||||
*b = p;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
if (i > z.i) {
|
||||
memset(p, z.i, i - z.i);
|
||||
}
|
||||
z.i = i;
|
||||
p[z.i] = 0;
|
||||
if (!IsTiny() && W == 8) {
|
||||
z.i |= (size_t)APPEND_COOKIE << 48;
|
||||
}
|
||||
*(size_t *)(p + z.n - W) = z.i;
|
||||
return i;
|
||||
}
|
|
@ -20,8 +20,18 @@
|
|||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Appends string to buffer.
|
||||
* Appends string to buffer, e.g.
|
||||
*
|
||||
* char *b = 0;
|
||||
* appends(&b, "hello");
|
||||
* free(b);
|
||||
*
|
||||
* The resulting buffer is guaranteed to be NUL-terminated, i.e.
|
||||
* `!b[appendz(b).i]` will be the case.
|
||||
*
|
||||
* @return bytes appended (always `strlen(s)`) or -1 if `ENOMEM`
|
||||
* @see appendz(b).i to get buffer length
|
||||
*/
|
||||
int appends(char **b, const char *s) {
|
||||
ssize_t appends(char **b, const char *s) {
|
||||
return appendd(b, s, strlen(s));
|
||||
}
|
||||
|
|
|
@ -19,15 +19,33 @@
|
|||
#include "libc/bits/bits.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* Appends string to buffer.
|
||||
* Appends character or word-encoded string to buffer.
|
||||
*
|
||||
* Up to eight characters can be appended. For example:
|
||||
*
|
||||
* appendw(&s, 'h'|'i'<<8);
|
||||
*
|
||||
* Is equivalent to:
|
||||
*
|
||||
* appends(&s, "hi");
|
||||
*
|
||||
* The special case:
|
||||
*
|
||||
* appendw(&s, 0);
|
||||
*
|
||||
* Will append a single NUL character.
|
||||
*
|
||||
* The resulting buffer is guaranteed to be NUL-terminated, i.e.
|
||||
* `!b[appendz(b).i]` will be the case.
|
||||
*
|
||||
* @return bytes appended or -1 if `ENOMEM`
|
||||
*/
|
||||
int appendw(char **b, uint64_t w) {
|
||||
ssize_t appendw(char **b, uint64_t w) {
|
||||
char t[8];
|
||||
unsigned l;
|
||||
if (!w) return 0;
|
||||
unsigned n = 1;
|
||||
WRITE64LE(t, w);
|
||||
return appendd(b, t, (bsrl(w) >> 3) + 1);
|
||||
if (w) n += bsrl(w) >> 3;
|
||||
return appendd(b, t, n);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
/**
|
||||
* Returns size of append buffer.
|
||||
*
|
||||
* @return i is number of bytes stored in buffer
|
||||
* @return n is number of bytes in allocation
|
||||
*/
|
||||
struct appendz appendz(char *p) {
|
||||
struct appendz z;
|
||||
|
|
|
@ -55,6 +55,10 @@ o/$(MODE)/libc/stdio/fputc.o: \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-O3
|
||||
|
||||
o//libc/stdio/appendw.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-O2
|
||||
|
||||
LIBC_STDIO_LIBS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)))
|
||||
LIBC_STDIO_SRCS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_STDIO_HDRS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_HDRS))
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#define W sizeof(size_t)
|
||||
|
||||
/**
|
||||
* Appends data to buffer.
|
||||
* Appends formatted string to buffer.
|
||||
*/
|
||||
int(vappendf)(char **b, const char *f, va_list v) {
|
||||
ssize_t(vappendf)(char **b, const char *f, va_list v) {
|
||||
char *p;
|
||||
int r, s;
|
||||
va_list w;
|
||||
|
|
|
@ -258,126 +258,3 @@ TEST(getrandom, sanityTest) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, test) {
|
||||
MeasureEntropy(kMoby, 1000);
|
||||
EXPECT_EQ(00, lroundl(10 * MeasureEntropy(" ", 12)));
|
||||
EXPECT_EQ(16, lroundl(10 * MeasureEntropy("abcabcabcabc", 12)));
|
||||
EXPECT_EQ(36, lroundl(10 * MeasureEntropy("abcdefghijkl", 12)));
|
||||
EXPECT_EQ(49, lroundl(10 * MeasureEntropy(kMoby, 512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testElfExecutable) {
|
||||
EXPECT_EQ(19, lroundl(10 * MeasureEntropy("\
|
||||
\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x03\x00\x3e\x00\x01\x00\x00\x00\x18\xd7\x00\x00\x00\x00\x00\x00\
|
||||
\x40\x00\x00\x00\x00\x00\x00\x00\xc8\xd0\x0c\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x40\x00\x38\x00\x09\x00\x40\x00\x16\x00\x15\x00\
|
||||
\x06\x00\x00\x00\x04\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x40\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\
|
||||
\xf8\x01\x00\x00\x00\x00\x00\x00\xf8\x01\x00\x00\x00\x00\x00\x00\
|
||||
\x08\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\
|
||||
\x38\x02\x00\x00\x00\x00\x00\x00\x38\x02\x00\x00\x00\x00\x00\x00\
|
||||
\x38\x02\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x19\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x90\xbc\x00\x00\x00\x00\x00\x00\x90\xbc\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x10\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\
|
||||
\x00\xc0\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\
|
||||
\x00\xc0\x00\x00\x00\x00\x00\x00\x62\xb2\x09\x00\x00\x00\x00\x00\
|
||||
\x62\xb2\x09\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\
|
||||
\x01\x00\x00\x00\x04\x00\x00\x00\x00\x80\x0a\x00\x00\x00\x00\x00\
|
||||
\x00\x80\x0a\x00\x00\x00\x00\x00\x00\x80\x0a\x00\x00\x00\x00\x00\
|
||||
\xe4\x09\x02\x00\x00\x00\x00\x00\xe4\x09\x02\x00\x00\x00\x00\x00\
|
||||
\x00\x10\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\
|
||||
\xc0\x95\x0c\x00\x00\x00\x00\x00\xc0\xa5\x0c\x00\x00\x00\x00\x00\
|
||||
\xc0\xa5\x0c\x00\x00\x00\x00\x00\x64\x3a\x00\x00\x00\x00\x00\x00\
|
||||
\xa8\x42\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\
|
||||
\x02\x00\x00\x00\x06\x00\x00\x00\xa0\xc2\x0c\x00\x00\x00\x00\x00\
|
||||
\xa0\xd2\x0c\x00\x00\x00\x00\x00\xa0\xd2\x0c\x00\x00\x00\x00\x00\
|
||||
\x80\x01\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\
|
||||
\x08\x00\x00\x00\x00\x00\x00\x00\x51\xe5\x74\x64\x06\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00",
|
||||
512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testApeExecutable) {
|
||||
EXPECT_EQ(53, lroundl(10 * MeasureEntropy("\
|
||||
\x7f\x45\x4c\x46\x02\x01\x01\x09\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x02\x00\x3e\x00\x01\x00\x00\x00\x0a\x11\x40\x00\x00\x00\x00\x00\
|
||||
\xe0\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x40\x00\x38\x00\x04\x00\x00\x00\x00\x00\x00\x00\
|
||||
\xb2\x40\xeb\x00\xeb\x14\x90\x90\xeb\x06\x48\x83\xec\x08\x31\xd2\
|
||||
\xbd\x00\x00\xeb\x05\xe9\xb0\x10\x00\x00\xfc\x0f\x1f\x87\x3e\xe0\
|
||||
\xbf\x00\x70\x31\xc9\x8e\xc1\xfa\x8e\xd7\x89\xcc\xfb\x0e\x1f\xe8\
|
||||
\x00\x00\x5e\x81\xee\x72\x00\xb8\x00\x02\x50\x50\x07\x31\xff\xb9\
|
||||
\x00\x02\xf3\xa4\x0f\x1f\x87\xd2\xff\xea\x8e\x20\x00\x00\x8e\xd9\
|
||||
\xb9\x00\x1b\xb8\x50\x00\x8e\xc0\x31\xc0\x31\xff\xf3\xaa\x80\xfa\
|
||||
\x40\x74\x13\xe8\x15\x00\x07\xb0\x01\x31\xc9\x30\xf6\xbf\x40\x03\
|
||||
\xe8\x48\x00\x4f\x75\xfa\xea\x20\x25\x00\x00\x53\x52\xb4\x08\xcd\
|
||||
\x13\x72\x2c\x88\xcf\x80\xe7\x3f\x80\xe1\xc0\xd0\xc1\xd0\xc1\x86\
|
||||
\xcd\x1e\x06\x1f\x31\xf6\x8e\xc6\xbe\x10\x15\x87\xf7\xa5\xa5\xa5\
|
||||
\xa5\xa5\xa4\x1f\x93\xab\x91\xab\x92\xab\x58\xaa\x92\x5b\xc3\x5a\
|
||||
\x80\xf2\x80\x31\xc0\xcd\x13\x72\xf7\xeb\xc1\x50\x51\x86\xcd\xd0\
|
||||
\xc9\xd0\xc9\x08\xc1\x31\xdb\xb0\x01\xb4\x02\xcd\x13\x59\x58\x72\
|
||||
\x1d\x8c\xc6\x83\xc6\x20\x8e\xc6\xfe\xc0\x3a\x06\x1c\x15\x76\x0d\
|
||||
\xb0\x01\xfe\xc6\x3a\x36\x20\x15\x76\x03\x30\xf6\x41\xc3\x50\x31\
|
||||
\xc0\xcd\x13\x58\xeb\xc5\x89\xfe\xac\x84\xc0\x74\x09\xbb\x07\x00\
|
||||
\xb4\x0e\xcd\x10\xeb\xf2\xc3\x57\xbf\x78\x24\xe8\xe8\xff\x5f\xe8\
|
||||
\xe4\xff\xbf\x80\x24\xe8\xde\xff\xf3\x90\xeb\xfc\xb9\x04\x00\xbe\
|
||||
\x00\x04\xad\x85\xc0\x74\x0b\x51\x56\x97\xbe\x9e\x24\xe8\x05\x00\
|
||||
\x5e\x59\xe2\xee\xc3\x89\xfa\x85\xd2\x74\x14\x52\x56\x31\xc9\xb1\
|
||||
\x03\x01\xca\xac\x5e\x0c\x80\xee\x5a\xac\xee\x42\x49\x79\xfa\xc3\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\xaa",
|
||||
512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testDevUrandom) {
|
||||
EXPECT_EQ(76, lroundl(10 * MeasureEntropy("\
|
||||
\x67\xa6\x8f\x6f\x6f\x01\xa4\x60\xa5\x5a\x6a\xfa\x06\xfd\xbb\xbe\
|
||||
\xe4\x73\x2f\xc4\x20\x25\xd9\xb2\x78\x7d\x9f\xaf\x5d\x03\x49\x01\
|
||||
\x90\x94\x8a\xc0\x33\x78\xe0\x65\xd8\x9c\x19\x96\x25\x90\xc8\x6e\
|
||||
\xf2\x65\xac\x72\xd9\x8e\x58\x05\x26\x22\xa3\x58\x41\x40\xee\x3c\
|
||||
\x3a\xb0\x08\x7c\x70\x0e\x23\xdc\x52\x10\x21\x5c\xb7\x3d\x3a\xce\
|
||||
\x7c\xd7\x2a\x8c\x35\x0c\x21\x2b\x03\x75\xbe\x0c\x49\x5b\xdb\x7a\
|
||||
\x7e\xeb\x27\x03\x56\xca\x9f\xf8\x00\xb4\x4d\x5b\xd6\xde\x41\xd6\
|
||||
\x86\x7b\x3c\x13\xd4\x2d\xd4\xe9\x79\x05\x48\xcc\xa5\x17\xf8\xb6\
|
||||
\x74\xdf\x39\x70\x32\x64\x70\x10\xfb\x53\x06\x87\xef\xff\x9f\x4c\
|
||||
\x07\xee\x09\x54\xb8\xda\x1a\x49\x9b\x12\x3a\xf9\xc3\x55\xbc\xa5\
|
||||
\xad\x6c\x3d\x1f\x39\x84\xc6\xac\x45\x14\x4f\xa9\xfc\xd6\xfb\xce\
|
||||
\x41\xf8\x78\x85\xe5\x72\x9c\x0c\xd3\x81\x9b\xa4\x72\xc9\xd5\xc8\
|
||||
\xc2\x3c\xcc\x36\x58\xf6\x23\x2a\x2e\x9c\x38\xea\x73\x17\xf0\x72\
|
||||
\x2d\x57\xf8\xc5\x62\x84\xb7\xce\x24\x7b\x46\x65\xc7\xf3\x78\x88\
|
||||
\x77\x36\x93\x25\x5d\x78\xc9\xfb\x24\xbb\xec\x2f\x77\x4f\x82\xd8\
|
||||
\x63\x23\xd1\x39\x54\x78\x14\x7d\x24\xc8\x1a\xed\x32\x2d\x7b\xdc\
|
||||
\xf4\x92\xb1\xaf\x0d\x9b\xba\xb6\x72\xfb\xb2\x7f\x8f\xd5\x4c\x5e\
|
||||
\x05\xa7\x05\x15\xc5\x51\xd0\x86\x0a\xce\x04\x84\x1e\xba\x44\xf3\
|
||||
\xbc\x09\xa9\x4e\xc1\xc7\xbd\x7e\x45\x38\x04\xa3\x6c\xfa\x46\x57\
|
||||
\x40\x93\xbf\xdd\x12\x05\x6c\xb0\xee\x08\x40\x74\xc9\xda\xe7\x30\
|
||||
\xfa\x1f\x12\xc8\x31\x33\x53\xe4\x65\x2a\xe8\xbf\x2b\x3c\xd6\xcc\
|
||||
\xec\x8f\x9a\x6f\xe1\xe0\xe6\x81\x0a\xf5\x46\x07\xeb\xcd\xba\xcb\
|
||||
\xa1\xe5\x4a\x42\xd6\x20\xce\xb6\x16\xcf\x73\x30\x25\x17\xe3\x00\
|
||||
\x2b\x58\x93\x86\x74\x57\x48\x8b\x2a\x35\x88\xc7\x84\x18\x53\x23\
|
||||
\xba\xc3\x06\x0a\xd7\x09\xf2\xcb\xe1\xb1\x39\x07\xaf\x2d\xb2\xbc\
|
||||
\x7d\x71\x91\x6f\x71\x53\x82\xed\x51\x96\xbf\x90\xb4\x4a\x9a\x20\
|
||||
\x21\x8a\x72\xa3\xbc\xfc\xb9\xcd\x47\x5e\x38\x9c\xd2\xf9\xae\x7f\
|
||||
\xb2\x1a\x2a\x81\x68\x31\x53\xb2\x11\xfa\x80\x71\x31\xdd\xde\x56\
|
||||
\x9c\x5f\x3f\x50\xb5\x5f\x99\x5d\x36\x34\x23\x13\xa9\xf0\x04\x3d\
|
||||
\xa0\xee\x1c\xe5\xe3\x8d\x60\x76\x62\x5a\xd2\xa3\xa2\x51\xea\x75\
|
||||
\xab\x1f\x2f\xc4\x08\x35\x5d\xf3\x28\x5d\x59\x67\x88\xf0\x61\x6c\
|
||||
\x8b\x5f\xaf\x90\xa9\x90\xfe\x36\x29\xcc\x02\xf7\x2f\xa7\x19\x0e",
|
||||
512)));
|
||||
}
|
||||
|
||||
BENCH(getrandom, bench) {
|
||||
EZBENCH2("MeasureEntropy", donothing, MeasureEntropy(kMoby, 512));
|
||||
}
|
||||
|
|
146
test/libc/rand/measureentropy_test.c
Normal file
146
test/libc/rand/measureentropy_test.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(MeasureEntropy, test) {
|
||||
MeasureEntropy(kMoby, 1000);
|
||||
EXPECT_EQ(00, lroundl(10 * MeasureEntropy(" ", 12)));
|
||||
EXPECT_EQ(16, lroundl(10 * MeasureEntropy("abcabcabcabc", 12)));
|
||||
EXPECT_EQ(36, lroundl(10 * MeasureEntropy("abcdefghijkl", 12)));
|
||||
EXPECT_EQ(49, lroundl(10 * MeasureEntropy(kMoby, 512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testElfExecutable) {
|
||||
EXPECT_EQ(19, lroundl(10 * MeasureEntropy("\
|
||||
\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x03\x00\x3e\x00\x01\x00\x00\x00\x18\xd7\x00\x00\x00\x00\x00\x00\
|
||||
\x40\x00\x00\x00\x00\x00\x00\x00\xc8\xd0\x0c\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x40\x00\x38\x00\x09\x00\x40\x00\x16\x00\x15\x00\
|
||||
\x06\x00\x00\x00\x04\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x40\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\
|
||||
\xf8\x01\x00\x00\x00\x00\x00\x00\xf8\x01\x00\x00\x00\x00\x00\x00\
|
||||
\x08\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\
|
||||
\x38\x02\x00\x00\x00\x00\x00\x00\x38\x02\x00\x00\x00\x00\x00\x00\
|
||||
\x38\x02\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x19\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x90\xbc\x00\x00\x00\x00\x00\x00\x90\xbc\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x10\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\
|
||||
\x00\xc0\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\
|
||||
\x00\xc0\x00\x00\x00\x00\x00\x00\x62\xb2\x09\x00\x00\x00\x00\x00\
|
||||
\x62\xb2\x09\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\
|
||||
\x01\x00\x00\x00\x04\x00\x00\x00\x00\x80\x0a\x00\x00\x00\x00\x00\
|
||||
\x00\x80\x0a\x00\x00\x00\x00\x00\x00\x80\x0a\x00\x00\x00\x00\x00\
|
||||
\xe4\x09\x02\x00\x00\x00\x00\x00\xe4\x09\x02\x00\x00\x00\x00\x00\
|
||||
\x00\x10\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\
|
||||
\xc0\x95\x0c\x00\x00\x00\x00\x00\xc0\xa5\x0c\x00\x00\x00\x00\x00\
|
||||
\xc0\xa5\x0c\x00\x00\x00\x00\x00\x64\x3a\x00\x00\x00\x00\x00\x00\
|
||||
\xa8\x42\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\
|
||||
\x02\x00\x00\x00\x06\x00\x00\x00\xa0\xc2\x0c\x00\x00\x00\x00\x00\
|
||||
\xa0\xd2\x0c\x00\x00\x00\x00\x00\xa0\xd2\x0c\x00\x00\x00\x00\x00\
|
||||
\x80\x01\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\
|
||||
\x08\x00\x00\x00\x00\x00\x00\x00\x51\xe5\x74\x64\x06\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00",
|
||||
512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testApeExecutable) {
|
||||
EXPECT_EQ(53, lroundl(10 * MeasureEntropy("\
|
||||
\x7f\x45\x4c\x46\x02\x01\x01\x09\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x02\x00\x3e\x00\x01\x00\x00\x00\x0a\x11\x40\x00\x00\x00\x00\x00\
|
||||
\xe0\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x40\x00\x38\x00\x04\x00\x00\x00\x00\x00\x00\x00\
|
||||
\xb2\x40\xeb\x00\xeb\x14\x90\x90\xeb\x06\x48\x83\xec\x08\x31\xd2\
|
||||
\xbd\x00\x00\xeb\x05\xe9\xb0\x10\x00\x00\xfc\x0f\x1f\x87\x3e\xe0\
|
||||
\xbf\x00\x70\x31\xc9\x8e\xc1\xfa\x8e\xd7\x89\xcc\xfb\x0e\x1f\xe8\
|
||||
\x00\x00\x5e\x81\xee\x72\x00\xb8\x00\x02\x50\x50\x07\x31\xff\xb9\
|
||||
\x00\x02\xf3\xa4\x0f\x1f\x87\xd2\xff\xea\x8e\x20\x00\x00\x8e\xd9\
|
||||
\xb9\x00\x1b\xb8\x50\x00\x8e\xc0\x31\xc0\x31\xff\xf3\xaa\x80\xfa\
|
||||
\x40\x74\x13\xe8\x15\x00\x07\xb0\x01\x31\xc9\x30\xf6\xbf\x40\x03\
|
||||
\xe8\x48\x00\x4f\x75\xfa\xea\x20\x25\x00\x00\x53\x52\xb4\x08\xcd\
|
||||
\x13\x72\x2c\x88\xcf\x80\xe7\x3f\x80\xe1\xc0\xd0\xc1\xd0\xc1\x86\
|
||||
\xcd\x1e\x06\x1f\x31\xf6\x8e\xc6\xbe\x10\x15\x87\xf7\xa5\xa5\xa5\
|
||||
\xa5\xa5\xa4\x1f\x93\xab\x91\xab\x92\xab\x58\xaa\x92\x5b\xc3\x5a\
|
||||
\x80\xf2\x80\x31\xc0\xcd\x13\x72\xf7\xeb\xc1\x50\x51\x86\xcd\xd0\
|
||||
\xc9\xd0\xc9\x08\xc1\x31\xdb\xb0\x01\xb4\x02\xcd\x13\x59\x58\x72\
|
||||
\x1d\x8c\xc6\x83\xc6\x20\x8e\xc6\xfe\xc0\x3a\x06\x1c\x15\x76\x0d\
|
||||
\xb0\x01\xfe\xc6\x3a\x36\x20\x15\x76\x03\x30\xf6\x41\xc3\x50\x31\
|
||||
\xc0\xcd\x13\x58\xeb\xc5\x89\xfe\xac\x84\xc0\x74\x09\xbb\x07\x00\
|
||||
\xb4\x0e\xcd\x10\xeb\xf2\xc3\x57\xbf\x78\x24\xe8\xe8\xff\x5f\xe8\
|
||||
\xe4\xff\xbf\x80\x24\xe8\xde\xff\xf3\x90\xeb\xfc\xb9\x04\x00\xbe\
|
||||
\x00\x04\xad\x85\xc0\x74\x0b\x51\x56\x97\xbe\x9e\x24\xe8\x05\x00\
|
||||
\x5e\x59\xe2\xee\xc3\x89\xfa\x85\xd2\x74\x14\x52\x56\x31\xc9\xb1\
|
||||
\x03\x01\xca\xac\x5e\x0c\x80\xee\x5a\xac\xee\x42\x49\x79\xfa\xc3\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
|
||||
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\xaa",
|
||||
512)));
|
||||
}
|
||||
|
||||
TEST(MeasureEntropy, testDevUrandom) {
|
||||
EXPECT_EQ(76, lroundl(10 * MeasureEntropy("\
|
||||
\x67\xa6\x8f\x6f\x6f\x01\xa4\x60\xa5\x5a\x6a\xfa\x06\xfd\xbb\xbe\
|
||||
\xe4\x73\x2f\xc4\x20\x25\xd9\xb2\x78\x7d\x9f\xaf\x5d\x03\x49\x01\
|
||||
\x90\x94\x8a\xc0\x33\x78\xe0\x65\xd8\x9c\x19\x96\x25\x90\xc8\x6e\
|
||||
\xf2\x65\xac\x72\xd9\x8e\x58\x05\x26\x22\xa3\x58\x41\x40\xee\x3c\
|
||||
\x3a\xb0\x08\x7c\x70\x0e\x23\xdc\x52\x10\x21\x5c\xb7\x3d\x3a\xce\
|
||||
\x7c\xd7\x2a\x8c\x35\x0c\x21\x2b\x03\x75\xbe\x0c\x49\x5b\xdb\x7a\
|
||||
\x7e\xeb\x27\x03\x56\xca\x9f\xf8\x00\xb4\x4d\x5b\xd6\xde\x41\xd6\
|
||||
\x86\x7b\x3c\x13\xd4\x2d\xd4\xe9\x79\x05\x48\xcc\xa5\x17\xf8\xb6\
|
||||
\x74\xdf\x39\x70\x32\x64\x70\x10\xfb\x53\x06\x87\xef\xff\x9f\x4c\
|
||||
\x07\xee\x09\x54\xb8\xda\x1a\x49\x9b\x12\x3a\xf9\xc3\x55\xbc\xa5\
|
||||
\xad\x6c\x3d\x1f\x39\x84\xc6\xac\x45\x14\x4f\xa9\xfc\xd6\xfb\xce\
|
||||
\x41\xf8\x78\x85\xe5\x72\x9c\x0c\xd3\x81\x9b\xa4\x72\xc9\xd5\xc8\
|
||||
\xc2\x3c\xcc\x36\x58\xf6\x23\x2a\x2e\x9c\x38\xea\x73\x17\xf0\x72\
|
||||
\x2d\x57\xf8\xc5\x62\x84\xb7\xce\x24\x7b\x46\x65\xc7\xf3\x78\x88\
|
||||
\x77\x36\x93\x25\x5d\x78\xc9\xfb\x24\xbb\xec\x2f\x77\x4f\x82\xd8\
|
||||
\x63\x23\xd1\x39\x54\x78\x14\x7d\x24\xc8\x1a\xed\x32\x2d\x7b\xdc\
|
||||
\xf4\x92\xb1\xaf\x0d\x9b\xba\xb6\x72\xfb\xb2\x7f\x8f\xd5\x4c\x5e\
|
||||
\x05\xa7\x05\x15\xc5\x51\xd0\x86\x0a\xce\x04\x84\x1e\xba\x44\xf3\
|
||||
\xbc\x09\xa9\x4e\xc1\xc7\xbd\x7e\x45\x38\x04\xa3\x6c\xfa\x46\x57\
|
||||
\x40\x93\xbf\xdd\x12\x05\x6c\xb0\xee\x08\x40\x74\xc9\xda\xe7\x30\
|
||||
\xfa\x1f\x12\xc8\x31\x33\x53\xe4\x65\x2a\xe8\xbf\x2b\x3c\xd6\xcc\
|
||||
\xec\x8f\x9a\x6f\xe1\xe0\xe6\x81\x0a\xf5\x46\x07\xeb\xcd\xba\xcb\
|
||||
\xa1\xe5\x4a\x42\xd6\x20\xce\xb6\x16\xcf\x73\x30\x25\x17\xe3\x00\
|
||||
\x2b\x58\x93\x86\x74\x57\x48\x8b\x2a\x35\x88\xc7\x84\x18\x53\x23\
|
||||
\xba\xc3\x06\x0a\xd7\x09\xf2\xcb\xe1\xb1\x39\x07\xaf\x2d\xb2\xbc\
|
||||
\x7d\x71\x91\x6f\x71\x53\x82\xed\x51\x96\xbf\x90\xb4\x4a\x9a\x20\
|
||||
\x21\x8a\x72\xa3\xbc\xfc\xb9\xcd\x47\x5e\x38\x9c\xd2\xf9\xae\x7f\
|
||||
\xb2\x1a\x2a\x81\x68\x31\x53\xb2\x11\xfa\x80\x71\x31\xdd\xde\x56\
|
||||
\x9c\x5f\x3f\x50\xb5\x5f\x99\x5d\x36\x34\x23\x13\xa9\xf0\x04\x3d\
|
||||
\xa0\xee\x1c\xe5\xe3\x8d\x60\x76\x62\x5a\xd2\xa3\xa2\x51\xea\x75\
|
||||
\xab\x1f\x2f\xc4\x08\x35\x5d\xf3\x28\x5d\x59\x67\x88\xf0\x61\x6c\
|
||||
\x8b\x5f\xaf\x90\xa9\x90\xfe\x36\x29\xcc\x02\xf7\x2f\xa7\x19\x0e",
|
||||
512)));
|
||||
}
|
||||
|
||||
BENCH(getrandom, bench) {
|
||||
EZBENCH2("MeasureEntropy", donothing, MeasureEntropy(kMoby, 512));
|
||||
}
|
|
@ -22,14 +22,17 @@
|
|||
|
||||
TEST(vappendf, test) {
|
||||
char *b = 0;
|
||||
appendf(&b, "hello ");
|
||||
ASSERT_NE(-1, appendf(&b, "hello "));
|
||||
EXPECT_EQ(6, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
EXPECT_EQ(6, strlen(b)); // guarantees nul terminator
|
||||
appendf(&b, " world\n");
|
||||
ASSERT_NE(-1, appendf(&b, " world\n"));
|
||||
EXPECT_EQ(13, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
EXPECT_EQ(13, strlen(b));
|
||||
appendd(&b, "\0", 1); // supports binary
|
||||
ASSERT_NE(-1, appendd(&b, "\0", 1)); // supports binary
|
||||
EXPECT_EQ(14, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
EXPECT_EQ(13, strlen(b));
|
||||
EXPECT_EQ(0, b[13]);
|
||||
EXPECT_EQ(0, b[14]);
|
||||
|
@ -37,12 +40,17 @@ TEST(vappendf, test) {
|
|||
free(b);
|
||||
}
|
||||
|
||||
TEST(vappends, test) {
|
||||
TEST(appends, test) {
|
||||
char *b = 0;
|
||||
appends(&b, "hello ");
|
||||
ASSERT_NE(-1, appends(&b, ""));
|
||||
EXPECT_NE(0, b);
|
||||
EXPECT_EQ(0, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
ASSERT_NE(-1, appends(&b, "hello "));
|
||||
EXPECT_EQ(6, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
EXPECT_EQ(6, strlen(b)); // guarantees nul terminator
|
||||
appends(&b, " world\n");
|
||||
ASSERT_NE(-1, appends(&b, " world\n"));
|
||||
EXPECT_EQ(13, appendz(b).i);
|
||||
EXPECT_EQ(13, strlen(b));
|
||||
EXPECT_EQ(0, b[13]);
|
||||
|
@ -50,6 +58,69 @@ TEST(vappends, test) {
|
|||
free(b);
|
||||
}
|
||||
|
||||
TEST(appendd, test) {
|
||||
char *b = 0;
|
||||
ASSERT_NE(-1, appendd(&b, 0, 0));
|
||||
EXPECT_NE(0, b);
|
||||
EXPECT_EQ(0, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
ASSERT_NE(-1, appendd(&b, "hello ", 6));
|
||||
EXPECT_EQ(6, appendz(b).i);
|
||||
EXPECT_EQ(0, b[appendz(b).i]);
|
||||
EXPECT_EQ(6, strlen(b)); // guarantees nul terminator
|
||||
ASSERT_NE(-1, appendd(&b, " world\n", 7));
|
||||
EXPECT_EQ(13, appendz(b).i);
|
||||
EXPECT_EQ(13, strlen(b));
|
||||
EXPECT_EQ(0, b[13]);
|
||||
EXPECT_STREQ("hello world\n", b);
|
||||
free(b);
|
||||
}
|
||||
|
||||
TEST(appendw, test) {
|
||||
char *b = 0;
|
||||
ASSERT_NE(-1, appendw(&b, 0));
|
||||
EXPECT_EQ(1, appendz(b).i);
|
||||
EXPECT_EQ(0, b[0]);
|
||||
EXPECT_EQ(0, b[1]);
|
||||
ASSERT_NE(-1, appendw(&b, 'h'));
|
||||
EXPECT_EQ(2, appendz(b).i);
|
||||
EXPECT_EQ(0, b[0]);
|
||||
EXPECT_EQ('h', b[1]);
|
||||
EXPECT_EQ(0, b[2]);
|
||||
ASSERT_NE(-1, appendw(&b, 'e' | 'l' << 8 | 'l' << 16 | 'o' << 24 |
|
||||
(uint64_t)'!' << 32));
|
||||
EXPECT_EQ(7, appendz(b).i);
|
||||
EXPECT_EQ(0, b[0]);
|
||||
EXPECT_EQ('h', b[1]);
|
||||
EXPECT_EQ('e', b[2]);
|
||||
EXPECT_EQ('l', b[3]);
|
||||
EXPECT_EQ('l', b[4]);
|
||||
EXPECT_EQ('o', b[5]);
|
||||
EXPECT_EQ('!', b[6]);
|
||||
EXPECT_EQ(0, b[7]);
|
||||
free(b);
|
||||
}
|
||||
|
||||
TEST(appendr, test) {
|
||||
char *b = 0;
|
||||
ASSERT_NE(-1, appends(&b, "hello"));
|
||||
EXPECT_EQ(5, appendz(b).i);
|
||||
ASSERT_NE(-1, appendr(&b, 1));
|
||||
EXPECT_EQ(0, strcmp(b, "h"));
|
||||
EXPECT_EQ(1, appendz(b).i);
|
||||
ASSERT_NE(-1, appendr(&b, 0));
|
||||
EXPECT_EQ(0, appendz(b).i);
|
||||
EXPECT_EQ(0, strcmp(b, ""));
|
||||
ASSERT_NE(-1, appendr(&b, 5));
|
||||
EXPECT_EQ(0, b[0]);
|
||||
EXPECT_EQ(0, b[1]);
|
||||
EXPECT_EQ(0, b[2]);
|
||||
EXPECT_EQ(0, b[3]);
|
||||
EXPECT_EQ(0, b[4]);
|
||||
EXPECT_EQ(0, b[5]);
|
||||
free(b);
|
||||
}
|
||||
|
||||
BENCH(vappendf, bench) {
|
||||
const char t[] = {0};
|
||||
char *b = 0;
|
||||
|
@ -57,6 +128,8 @@ BENCH(vappendf, bench) {
|
|||
free(b), b = 0;
|
||||
EZBENCH2("appends", donothing, appends(&b, "1"));
|
||||
free(b), b = 0;
|
||||
EZBENCH2("appendw", donothing, appendw(&b, 'B'));
|
||||
free(b), b = 0;
|
||||
EZBENCH2("appendd", donothing, appendd(&b, t, 1));
|
||||
free(b);
|
||||
free(b), b = 0;
|
||||
}
|
||||
|
|
9
third_party/lua/loadlib.c
vendored
9
third_party/lua/loadlib.c
vendored
|
@ -16,6 +16,8 @@
|
|||
#include "third_party/lua/lua.h"
|
||||
#include "third_party/lua/lualib.h"
|
||||
|
||||
const char *g_lua_path_default = LUA_PATH_DEFAULT;
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
|
@ -728,12 +730,17 @@ static void createclibstable (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
static const char *GetLuaPathDefault(void) {
|
||||
return g_lua_path_default;
|
||||
}
|
||||
|
||||
|
||||
LUAMOD_API int luaopen_package (lua_State *L) {
|
||||
createclibstable(L);
|
||||
luaL_newlib(L, pk_funcs); /* create 'package' table */
|
||||
createsearcherstable(L);
|
||||
/* set paths */
|
||||
setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
|
||||
setpath(L, "path", LUA_PATH_VAR, g_lua_path_default);
|
||||
setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
|
||||
/* store config information */
|
||||
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
|
||||
|
|
44
third_party/lua/lua.h
vendored
44
third_party/lua/lua.h
vendored
|
@ -1,15 +1,8 @@
|
|||
/*
|
||||
** $Id: lua.h $
|
||||
** Lua - A Scripting Language
|
||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||
** See Copyright Notice at the end of this file
|
||||
*/
|
||||
|
||||
#ifndef lua_h
|
||||
#define lua_h
|
||||
|
||||
#ifndef COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
||||
#include "third_party/lua/luaconf.h"
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/* clang-format off */
|
||||
|
||||
#define LUA_VERSION_MAJOR "5"
|
||||
|
@ -489,29 +482,8 @@ struct lua_Debug {
|
|||
|
||||
/* }====================================================================== */
|
||||
|
||||
extern const char *g_lua_path_default;
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2021 Lua.org, PUC-Rio.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#endif
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_ */
|
||||
|
|
5
third_party/lua/lua.mk
vendored
5
third_party/lua/lua.mk
vendored
|
@ -60,6 +60,11 @@ o/$(MODE)/third_party/lua/lauxlib.o: \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
$(THIRD_PARTY_LUA_OBJS): \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/lua
|
||||
o/$(MODE)/third_party/lua: \
|
||||
$(THIRD_PARTY_LUA_BINS) \
|
||||
|
|
79
third_party/lua/luaconf.h
vendored
79
third_party/lua/luaconf.h
vendored
|
@ -1,17 +1,13 @@
|
|||
/*
|
||||
** $Id: luaconf.h $
|
||||
** Configuration file for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef luaconf_h
|
||||
#define luaconf_h
|
||||
|
||||
#define LUA_USE_POSIX
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/limits.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
|
||||
#define LUA_USE_POSIX
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
|
@ -193,63 +189,20 @@
|
|||
*/
|
||||
|
||||
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
||||
#if defined(_WIN32) /* { */
|
||||
/*
|
||||
** In Windows, any exclamation mark ('!') in the path is replaced by the
|
||||
** path of the directory of the executable file of the current process.
|
||||
*/
|
||||
#define LUA_LDIR "!\\lua\\"
|
||||
#define LUA_CDIR "!\\"
|
||||
#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
|
||||
|
||||
#if !defined(LUA_PATH_DEFAULT)
|
||||
#define LUA_PATH_DEFAULT \
|
||||
LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
|
||||
LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
|
||||
LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
|
||||
".\\?.lua;" ".\\?\\init.lua"
|
||||
#endif
|
||||
|
||||
#if !defined(LUA_CPATH_DEFAULT)
|
||||
#define LUA_CPATH_DEFAULT \
|
||||
LUA_CDIR"?.dll;" \
|
||||
LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
|
||||
LUA_CDIR"loadall.dll;" ".\\?.dll"
|
||||
#endif
|
||||
|
||||
#else /* }{ */
|
||||
|
||||
#define LUA_ROOT "zip:"
|
||||
#define LUA_LDIR LUA_ROOT ".lua/"
|
||||
#define LUA_CDIR LUA_ROOT ".lua/"
|
||||
|
||||
#if !defined(LUA_PATH_DEFAULT)
|
||||
#define LUA_PATH_DEFAULT \
|
||||
LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua"
|
||||
#endif
|
||||
|
||||
#if !defined(LUA_CPATH_DEFAULT)
|
||||
#define LUA_CPATH_DEFAULT \
|
||||
LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
|
||||
#endif
|
||||
|
||||
#endif /* } */
|
||||
|
||||
#define LUA_PATH_DEFAULT LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" "./?.lua;" "./?/init.lua"
|
||||
#define LUA_CPATH_DEFAULT LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
|
||||
|
||||
/*
|
||||
@@ LUA_DIRSEP is the directory separator (for submodules).
|
||||
** CHANGE it if your machine does not use "/" as the directory separator
|
||||
** and is not Windows. (On Windows Lua automatically uses "\".)
|
||||
*/
|
||||
#if !defined(LUA_DIRSEP)
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define LUA_DIRSEP "\\"
|
||||
#else
|
||||
#define LUA_DIRSEP "/"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* }================================================================== */
|
||||
|
||||
|
@ -269,20 +222,8 @@
|
|||
** the libraries, you may want to use the following definition (define
|
||||
** LUA_BUILD_AS_DLL to get it).
|
||||
*/
|
||||
#if defined(LUA_BUILD_AS_DLL) /* { */
|
||||
|
||||
#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
|
||||
#define LUA_API __declspec(dllexport)
|
||||
#else /* }{ */
|
||||
#define LUA_API __declspec(dllimport)
|
||||
#endif /* } */
|
||||
|
||||
#else /* }{ */
|
||||
|
||||
#define LUA_API extern
|
||||
|
||||
#endif /* } */
|
||||
|
||||
|
||||
/*
|
||||
** More often than not the libs go together with the core.
|
||||
|
@ -305,12 +246,7 @@
|
|||
** give a warning about it. To avoid these warnings, change to the
|
||||
** default definition.
|
||||
*/
|
||||
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
|
||||
defined(__ELF__) /* { */
|
||||
#define LUAI_FUNC /* __attribute__((visibility("internal"))) */ extern
|
||||
#else /* }{ */
|
||||
#define LUAI_FUNC extern
|
||||
#endif /* } */
|
||||
|
||||
#define LUAI_DDEC(dec) LUAI_FUNC dec
|
||||
#define LUAI_DDEF /* empty */
|
||||
|
@ -710,8 +646,7 @@
|
|||
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
|
||||
** Define it as a help when debugging C code.
|
||||
*/
|
||||
#if defined(LUA_USE_APICHECK)
|
||||
#include <assert.h>
|
||||
#if IsModeDbg()
|
||||
#define luai_apicheck(l,e) assert(e)
|
||||
#endif
|
||||
|
||||
|
|
1
third_party/mbedtls/config.h
vendored
1
third_party/mbedtls/config.h
vendored
|
@ -2,6 +2,7 @@
|
|||
#define MBEDTLS_CONFIG_H_
|
||||
#include "libc/dce.h"
|
||||
|
||||
/* /\* uncomment for testing old cpu code paths *\/ */
|
||||
/* #include "libc/nexgen32e/x86feature.h" */
|
||||
/* #undef X86_HAVE */
|
||||
/* #define X86_HAVE(x) 0 */
|
||||
|
|
32
third_party/mbedtls/ecp384.c
vendored
32
third_party/mbedtls/ecp384.c
vendored
|
@ -35,21 +35,22 @@ mbedtls_p384_isz( uint64_t p[6] )
|
|||
return( !p[0] & !p[1] & !p[2] & !p[3] & !p[4] & !p[5] );
|
||||
}
|
||||
|
||||
bool mbedtls_p384_gte( uint64_t p[7] )
|
||||
static bool
|
||||
mbedtls_p384_gte( uint64_t p[7] )
|
||||
{
|
||||
return( (((int64_t)p[6] > 0) |
|
||||
(!p[6] &
|
||||
(p[5] > 0xffffffffffffffff |
|
||||
(p[5] == 0xffffffffffffffff &
|
||||
(p[4] > 0xffffffffffffffff |
|
||||
(p[4] == 0xffffffffffffffff &
|
||||
(p[3] > 0xffffffffffffffff |
|
||||
(p[3] == 0xffffffffffffffff &
|
||||
(p[2] > 0xfffffffffffffffe |
|
||||
(p[2] == 0xfffffffffffffffe &
|
||||
(p[1] > 0xffffffff00000000 |
|
||||
(p[1] == 0xffffffff00000000 &
|
||||
(p[0] > 0x00000000ffffffff |
|
||||
((p[5] > 0xffffffffffffffff) |
|
||||
((p[5] == 0xffffffffffffffff) &
|
||||
((p[4] > 0xffffffffffffffff) |
|
||||
((p[4] == 0xffffffffffffffff) &
|
||||
((p[3] > 0xffffffffffffffff) |
|
||||
((p[3] == 0xffffffffffffffff) &
|
||||
((p[2] > 0xfffffffffffffffe) |
|
||||
((p[2] == 0xfffffffffffffffe) &
|
||||
((p[1] > 0xffffffff00000000) |
|
||||
((p[1] == 0xffffffff00000000) &
|
||||
((p[0] > 0x00000000ffffffff) |
|
||||
(p[0] == 0x00000000ffffffff)))))))))))))) );
|
||||
}
|
||||
|
||||
|
@ -128,7 +129,8 @@ mbedtls_p384_gro( uint64_t p[7] )
|
|||
#endif
|
||||
}
|
||||
|
||||
void mbedtls_p384_rum( uint64_t p[7] )
|
||||
static inline void
|
||||
mbedtls_p384_rum( uint64_t p[7] )
|
||||
{
|
||||
while( mbedtls_p384_gte( p ) )
|
||||
mbedtls_p384_red( p );
|
||||
|
@ -142,9 +144,7 @@ void mbedtls_p384_mod( uint64_t X[12] )
|
|||
mbedtls_p384_gro(X);
|
||||
} while( (int64_t)X[6] < 0 );
|
||||
} else {
|
||||
while( mbedtls_p384_gte(X) ){
|
||||
mbedtls_p384_red(X);
|
||||
}
|
||||
mbedtls_p384_rum(X);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
third_party/mbedtls/ecp_internal.h
vendored
1
third_party/mbedtls/ecp_internal.h
vendored
|
@ -261,7 +261,6 @@ int mbedtls_p384_normalize_jac( const mbedtls_ecp_group *,
|
|||
int mbedtls_p384_normalize_jac_many( const mbedtls_ecp_group *,
|
||||
mbedtls_ecp_point *[], size_t );
|
||||
|
||||
void mbedtls_p384_rum( uint64_t p[7] );
|
||||
void mbedtls_p384_mod( uint64_t X[12] );
|
||||
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_MBEDTLS_ECP_INTERNAL_H_ */
|
||||
|
|
39
third_party/mbedtls/test/secp384r1_test.c
vendored
39
third_party/mbedtls/test/secp384r1_test.c
vendored
|
@ -27,6 +27,8 @@
|
|||
#include "third_party/mbedtls/math.h"
|
||||
#ifdef MBEDTLS_ECP_C
|
||||
|
||||
/*P=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff*/
|
||||
|
||||
int ecp_mod_p384_old(mbedtls_mpi *);
|
||||
|
||||
int GetEntropy(void *c, unsigned char *p, size_t n) {
|
||||
|
@ -97,14 +99,6 @@ TEST(secp384r1, needsDownwardCorrection) {
|
|||
|
||||
TEST(secp384r1, needsUpwardCorrection) {
|
||||
int i;
|
||||
uint64_t P[6] = {
|
||||
0x00000000ffffffff, //
|
||||
0xffffffff00000000, //
|
||||
0xfffffffffffffffe, //
|
||||
0xffffffffffffffff, //
|
||||
0xffffffffffffffff, //
|
||||
0xffffffffffffffff, //
|
||||
};
|
||||
uint64_t X[12] = {
|
||||
0x0000000000000000, //
|
||||
0x0000000000000000, //
|
||||
|
@ -136,6 +130,35 @@ TEST(secp384r1, needsUpwardCorrection) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(secp384r1, largestInput_quasiModNeedsTwoDownwardCorrections) {
|
||||
int i;
|
||||
uint64_t X[12] = {
|
||||
// X = (P-1)*(P-1)
|
||||
0xfffffffc00000004, //
|
||||
0x0000000400000000, //
|
||||
0xfffffffe00000002, //
|
||||
0x0000000200000000, //
|
||||
0x0000000000000001, //
|
||||
0x0000000000000000, //
|
||||
0x00000001fffffffc, //
|
||||
0xfffffffe00000000, //
|
||||
0xfffffffffffffffd, //
|
||||
0xffffffffffffffff, //
|
||||
0xffffffffffffffff, //
|
||||
0xffffffffffffffff, //
|
||||
};
|
||||
uint64_t W[12] /* W = X mod P */ = {
|
||||
0x0000000000000001, //
|
||||
};
|
||||
mbedtls_p384_mod(X);
|
||||
if (memcmp(W, X, 12 * 8)) {
|
||||
for (i = 0; i < 12; ++i) {
|
||||
printf("0x%016lx vs. 0x%016lx %d\n", W[i], X[i], W[i] == X[i]);
|
||||
}
|
||||
ASSERT_TRUE(false);
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(secp384r1, bench) {
|
||||
mbedtls_mpi A;
|
||||
mbedtls_mpi_init(&A);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SetStatus(200)
|
||||
SetHeader("Content-Type", GetHeader("Content-Type"))
|
||||
SetHeader("Content-Type", GetHeader("Content-Type") or "text/plain")
|
||||
Write(GetPayload())
|
||||
|
|
|
@ -244,7 +244,8 @@ SECURITY
|
|||
Subject Alternative Names (SAN) or the Common Name (CN) of subject if
|
||||
SAN isn't used. This means you don't need to reveal your whole domain
|
||||
portfolio to each client just to have ssl. You can just use different
|
||||
certificates for each domain if you choose to do so.
|
||||
certificates for each domain if you choose to do so. If redbean can't
|
||||
find an appropriate match, then the first certificate will be chosen.
|
||||
|
||||
Your redbean has been secured with algorithms so strong that, until a
|
||||
few decades ago, it was illegal to share them with with those outside
|
||||
|
|
|
@ -151,7 +151,6 @@ o/$(MODE)/tool/net/redbean-demo.com: \
|
|||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/host/third_party/infozip/zip.com -qj $@ tool/net/demo/404.html tool/net/favicon.ico tool/net/redbean.png tool/net/demo/redbean-form.lua tool/net/demo/redbean-xhr.lua tool/net/demo/printpayload.lua tool/net/demo/fetch.lua
|
||||
@echo Uncompressed for HTTP Range requests | $(COMPILE) -AZIP -T$@ o/$(MODE)/host/third_party/infozip/zip.com -cqj0 $@ tool/net/demo/seekable.txt
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/host/third_party/infozip/zip.com -q $@ tool/net/ tool/net/demo/ tool/net/demo/index.html tool/net/demo/redbean.css tool/net/redbean.c net/http/parsehttpmessage.c net/http/parseurl.c net/http/encodeurl.c test/net/http/parsehttpmessage_test.c test/net/http/parseurl_test.c
|
||||
@printf "<p>Thank you for using <a href=https://justine.lol/redbean/>redbean</a> the tiniest most vertically integrated actually portable web server with superior performance." | $(COMPILE) -AZIP -T$@ o/$(MODE)/host/third_party/infozip/zip.com -z $@
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/virtualbean.justine.lol/
|
||||
@$(COMPILE) -ACP -T$@ cp tool/net/redbean.png o/$(MODE)/tool/net/virtualbean.justine.lol/redbean.png
|
||||
@$(COMPILE) -ACP -T$@ cp tool/net/demo/virtualbean.html o/$(MODE)/tool/net/virtualbean.justine.lol/index.html
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
|
@ -91,6 +92,7 @@
|
|||
#include "third_party/lua/lauxlib.h"
|
||||
#include "third_party/lua/ltests.h"
|
||||
#include "third_party/lua/lua.h"
|
||||
#include "third_party/lua/luaconf.h"
|
||||
#include "third_party/lua/lualib.h"
|
||||
#include "third_party/mbedtls/asn1.h"
|
||||
#include "third_party/mbedtls/asn1write.h"
|
||||
|
@ -352,6 +354,7 @@ static uint32_t clientaddrsize;
|
|||
|
||||
static lua_State *L;
|
||||
static size_t zsize;
|
||||
static char *outbuf;
|
||||
static char *content;
|
||||
static uint8_t *zmap;
|
||||
static uint8_t *zbase;
|
||||
|
@ -384,7 +387,6 @@ static ssize_t (*generator)(struct iovec[3]);
|
|||
static struct Buffer inbuf;
|
||||
static struct Buffer oldin;
|
||||
static struct Buffer hdrbuf;
|
||||
static struct Buffer outbuf;
|
||||
static struct timeval timeout;
|
||||
static struct Buffer effectivepath;
|
||||
|
||||
|
@ -526,57 +528,14 @@ static void CollectGarbage(void) {
|
|||
}
|
||||
|
||||
static void UseOutput(void) {
|
||||
content = FreeLater(outbuf.p);
|
||||
contentlength = outbuf.n;
|
||||
outbuf.p = 0;
|
||||
outbuf.n = 0;
|
||||
outbuf.c = 0;
|
||||
content = FreeLater(outbuf);
|
||||
contentlength = appendz(outbuf).i;
|
||||
outbuf = 0;
|
||||
}
|
||||
|
||||
static void DropOutput(void) {
|
||||
FreeLater(outbuf.p);
|
||||
outbuf.p = 0;
|
||||
outbuf.n = 0;
|
||||
outbuf.c = 0;
|
||||
}
|
||||
|
||||
static void ClearOutput(void) {
|
||||
outbuf.n = 0;
|
||||
}
|
||||
|
||||
static void Grow(size_t n) {
|
||||
do {
|
||||
if (outbuf.c) {
|
||||
outbuf.c += outbuf.c >> 1;
|
||||
} else {
|
||||
outbuf.c = 16 * 1024;
|
||||
}
|
||||
} while (n > outbuf.c);
|
||||
outbuf.p = xrealloc(outbuf.p, outbuf.c);
|
||||
}
|
||||
|
||||
static void AppendData(const char *data, size_t size) {
|
||||
size_t n;
|
||||
n = outbuf.n + size;
|
||||
if (n > outbuf.c) Grow(n);
|
||||
memcpy(outbuf.p + outbuf.n, data, size);
|
||||
outbuf.n = n;
|
||||
}
|
||||
|
||||
static void Append(const char *fmt, ...) {
|
||||
int n;
|
||||
char *p;
|
||||
va_list va, vb;
|
||||
va_start(va, fmt);
|
||||
va_copy(vb, va);
|
||||
n = vsnprintf(outbuf.p + outbuf.n, outbuf.c - outbuf.n, fmt, va);
|
||||
if (n >= outbuf.c - outbuf.n) {
|
||||
Grow(outbuf.n + n + 1);
|
||||
vsnprintf(outbuf.p + outbuf.n, outbuf.c - outbuf.n, fmt, vb);
|
||||
}
|
||||
va_end(vb);
|
||||
va_end(va);
|
||||
outbuf.n += n;
|
||||
FreeLater(outbuf);
|
||||
outbuf = 0;
|
||||
}
|
||||
|
||||
static char *MergePaths(const char *p, size_t n, const char *q, size_t m,
|
||||
|
@ -641,9 +600,11 @@ static mbedtls_x509_crt *GetTrustedCertificate(mbedtls_x509_name *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void UseCertificate(mbedtls_ssl_config *c, struct Cert *kp) {
|
||||
VERBOSEF("using %s certificate %`'s", mbedtls_pk_get_name(&kp->cert->pk),
|
||||
gc(FormatX509Name(&kp->cert->subject)));
|
||||
static void UseCertificate(mbedtls_ssl_config *c, struct Cert *kp,
|
||||
const char *role) {
|
||||
VERBOSEF("using %s certificate %`'s for HTTPS %s",
|
||||
mbedtls_pk_get_name(&kp->cert->pk),
|
||||
gc(FormatX509Name(&kp->cert->subject)), role);
|
||||
CHECK_EQ(0, mbedtls_ssl_conf_own_cert(c, kp->cert, kp->key));
|
||||
}
|
||||
|
||||
|
@ -947,8 +908,8 @@ static void ProgramTimeout(long ms) {
|
|||
timeout.tv_sec = ms; /* -(keepalive seconds) */
|
||||
timeout.tv_usec = 0;
|
||||
} else {
|
||||
if (ms <= 30) {
|
||||
fprintf(stderr, "error: timeout needs to be 31ms or greater\n");
|
||||
if (ms < 10) {
|
||||
fprintf(stderr, "error: timeout needs to be 10ms or greater\n");
|
||||
exit(1);
|
||||
}
|
||||
d = ldiv(ms, 1000);
|
||||
|
@ -1168,57 +1129,57 @@ static void ReportWorkerExit(int pid, int ws) {
|
|||
}
|
||||
}
|
||||
|
||||
static void AppendResourceReport(struct rusage *ru, const char *nl) {
|
||||
static void AppendResourceReport(char **b, struct rusage *ru, const char *nl) {
|
||||
long utime, stime;
|
||||
long double ticks;
|
||||
if (ru->ru_maxrss) {
|
||||
Append("ballooned to %,ldkb in size%s", ru->ru_maxrss, nl);
|
||||
appendf(b, "ballooned to %,ldkb in size%s", ru->ru_maxrss, nl);
|
||||
}
|
||||
if ((utime = ru->ru_utime.tv_sec * 1000000 + ru->ru_utime.tv_usec) |
|
||||
(stime = ru->ru_stime.tv_sec * 1000000 + ru->ru_stime.tv_usec)) {
|
||||
ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK));
|
||||
Append("needed %,ldµs cpu (%d%% kernel)%s", utime + stime,
|
||||
(int)((long double)stime / (utime + stime) * 100), nl);
|
||||
appendf(b, "needed %,ldµs cpu (%d%% kernel)%s", utime + stime,
|
||||
(int)((long double)stime / (utime + stime) * 100), nl);
|
||||
if (ru->ru_idrss) {
|
||||
Append("needed %,ldkb memory on average%s", lroundl(ru->ru_idrss / ticks),
|
||||
nl);
|
||||
appendf(b, "needed %,ldkb memory on average%s",
|
||||
lroundl(ru->ru_idrss / ticks), nl);
|
||||
}
|
||||
if (ru->ru_isrss) {
|
||||
Append("needed %,ldkb stack on average%s", lroundl(ru->ru_isrss / ticks),
|
||||
nl);
|
||||
appendf(b, "needed %,ldkb stack on average%s",
|
||||
lroundl(ru->ru_isrss / ticks), nl);
|
||||
}
|
||||
if (ru->ru_ixrss) {
|
||||
Append("mapped %,ldkb shared on average%s", lroundl(ru->ru_ixrss / ticks),
|
||||
nl);
|
||||
appendf(b, "mapped %,ldkb shared on average%s",
|
||||
lroundl(ru->ru_ixrss / ticks), nl);
|
||||
}
|
||||
}
|
||||
if (ru->ru_minflt || ru->ru_majflt) {
|
||||
Append("caused %,ld page faults (%d%% memcpy)%s",
|
||||
ru->ru_minflt + ru->ru_majflt,
|
||||
(int)((long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) *
|
||||
100),
|
||||
nl);
|
||||
appendf(b, "caused %,ld page faults (%d%% memcpy)%s",
|
||||
ru->ru_minflt + ru->ru_majflt,
|
||||
(int)((long double)ru->ru_minflt / (ru->ru_minflt + ru->ru_majflt) *
|
||||
100),
|
||||
nl);
|
||||
}
|
||||
if (ru->ru_nvcsw + ru->ru_nivcsw > 1) {
|
||||
Append(
|
||||
"%,ld context switches (%d%% consensual)%s",
|
||||
appendf(
|
||||
b, "%,ld context switches (%d%% consensual)%s",
|
||||
ru->ru_nvcsw + ru->ru_nivcsw,
|
||||
(int)((long double)ru->ru_nvcsw / (ru->ru_nvcsw + ru->ru_nivcsw) * 100),
|
||||
nl);
|
||||
}
|
||||
if (ru->ru_msgrcv || ru->ru_msgsnd) {
|
||||
Append("received %,ld message%s and sent %,ld%s", ru->ru_msgrcv,
|
||||
ru->ru_msgrcv == 1 ? "" : "s", ru->ru_msgsnd, nl);
|
||||
appendf(b, "received %,ld message%s and sent %,ld%s", ru->ru_msgrcv,
|
||||
ru->ru_msgrcv == 1 ? "" : "s", ru->ru_msgsnd, nl);
|
||||
}
|
||||
if (ru->ru_inblock || ru->ru_oublock) {
|
||||
Append("performed %,ld read%s and %,ld write i/o operations%s",
|
||||
ru->ru_inblock, ru->ru_inblock == 1 ? "" : "s", ru->ru_oublock, nl);
|
||||
appendf(b, "performed %,ld read%s and %,ld write i/o operations%s",
|
||||
ru->ru_inblock, ru->ru_inblock == 1 ? "" : "s", ru->ru_oublock, nl);
|
||||
}
|
||||
if (ru->ru_nsignals) {
|
||||
Append("received %,ld signals%s", ru->ru_nsignals, nl);
|
||||
appendf(b, "received %,ld signals%s", ru->ru_nsignals, nl);
|
||||
}
|
||||
if (ru->ru_nswap) {
|
||||
Append("got swapped %,ld times%s", ru->ru_nswap, nl);
|
||||
appendf(b, "got swapped %,ld times%s", ru->ru_nswap, nl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1251,16 +1212,16 @@ static void AddRusage(struct rusage *x, const struct rusage *y) {
|
|||
}
|
||||
|
||||
static void ReportWorkerResources(int pid, struct rusage *ru) {
|
||||
const char *s;
|
||||
char *s, *b = 0;
|
||||
if (logrusage || LOGGABLE(kLogDebug)) {
|
||||
AppendResourceReport(ru, "\n");
|
||||
if (outbuf.n) {
|
||||
if ((s = IndentLines(outbuf.p, outbuf.n - 1, 0, 1))) {
|
||||
AppendResourceReport(&b, ru, "\n");
|
||||
if (b) {
|
||||
if ((s = IndentLines(b, appendz(b).i - 1, 0, 1))) {
|
||||
flogf(kLogInfo, __FILE__, __LINE__, NULL,
|
||||
"resource report for pid %d\n%s", pid, s);
|
||||
free(s);
|
||||
}
|
||||
ClearOutput();
|
||||
free(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1512,68 +1473,101 @@ static void WipeServingKeys(void) {
|
|||
/* mbedtls_ssl_key_cert_free(conf.key_cert); */
|
||||
}
|
||||
|
||||
static int TlsRouteCertificate(mbedtls_ssl_context *ssl, int i,
|
||||
const unsigned char *host, size_t size) {
|
||||
int rc;
|
||||
if (!(rc = mbedtls_ssl_set_hs_own_cert(ssl, certs.p[i].cert,
|
||||
certs.p[i].key))) {
|
||||
DEBUGF("TlsRoute(%`'.*s) %s %`'s", size, host,
|
||||
mbedtls_pk_get_name(&certs.p[i].cert->pk),
|
||||
gc(FormatX509Name(&certs.p[i].cert->subject)));
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
static bool CertHasCommonName(const mbedtls_x509_crt *cert,
|
||||
const unsigned char *host, size_t size) {
|
||||
const mbedtls_x509_name *name;
|
||||
for (name = &cert->subject; name; name = name->next) {
|
||||
if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid)) {
|
||||
if (SlicesEqualCase(host, size, name->val.p, name->val.len)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CertHasHost(const mbedtls_x509_crt *cert, const unsigned char *host,
|
||||
size_t size) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
SlicesEqualCase(host, size, cur->buf.p, cur->buf.len)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CertHasIp(const mbedtls_x509_crt *cert, uint32_t ip) {
|
||||
const mbedtls_x509_sequence *cur;
|
||||
for (cur = &cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_IP_ADDRESS &&
|
||||
cur->buf.len == 4 && ip == READ32BE(cur->buf.p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsServerCert(mbedtls_pk_type_t type, int i) {
|
||||
return certs.p[i].cert && certs.p[i].key && !certs.p[i].cert->ca_istrue &&
|
||||
mbedtls_pk_get_type(certs.p[i].key) == type &&
|
||||
!mbedtls_x509_crt_check_extended_key_usage(
|
||||
certs.p[i].cert, MBEDTLS_OID_SERVER_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH));
|
||||
}
|
||||
|
||||
static bool TlsRouteFind(mbedtls_pk_type_t type, mbedtls_ssl_context *ssl,
|
||||
const unsigned char *host, size_t size, int64_t ip) {
|
||||
int i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (IsServerCert(type, i) &&
|
||||
(((certs.p[i].cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) &&
|
||||
(ip == -1 ? CertHasHost(certs.p[i].cert, host, size)
|
||||
: CertHasIp(certs.p[i].cert, ip))) ||
|
||||
CertHasCommonName(certs.p[i].cert, host, size))) {
|
||||
CHECK_EQ(
|
||||
0, mbedtls_ssl_set_hs_own_cert(ssl, certs.p[i].cert, certs.p[i].key));
|
||||
DEBUGF("TlsRoute(%s, %`'.*s) %s %`'s", mbedtls_pk_type_name(type), size,
|
||||
host, mbedtls_pk_get_name(&certs.p[i].cert->pk),
|
||||
gc(FormatX509Name(&certs.p[i].cert->subject)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool TlsRouteFirst(mbedtls_pk_type_t type, mbedtls_ssl_context *ssl) {
|
||||
int i;
|
||||
for (i = 0; i < certs.n; ++i) {
|
||||
if (IsServerCert(type, i)) {
|
||||
CHECK_EQ(
|
||||
0, mbedtls_ssl_set_hs_own_cert(ssl, certs.p[i].cert, certs.p[i].key));
|
||||
DEBUGF("TlsRoute(%s) %s %`'s", mbedtls_pk_type_name(type),
|
||||
mbedtls_pk_get_name(&certs.p[i].cert->pk),
|
||||
gc(FormatX509Name(&certs.p[i].cert->subject)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int TlsRoute(void *ctx, mbedtls_ssl_context *ssl,
|
||||
const unsigned char *host, size_t size) {
|
||||
int rc;
|
||||
size_t i;
|
||||
int64_t ip;
|
||||
int santype;
|
||||
const mbedtls_x509_name *name;
|
||||
const mbedtls_x509_sequence *cur;
|
||||
bool ok1, ok2;
|
||||
ip = ParseIp((const char *)host, size);
|
||||
for (rc = -1, i = 0; i < certs.n; ++i) {
|
||||
if (!certs.p[i].key || !certs.p[i].cert || certs.p[i].cert->ca_istrue ||
|
||||
mbedtls_x509_crt_check_extended_key_usage(
|
||||
certs.p[i].cert, MBEDTLS_OID_SERVER_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH))) {
|
||||
continue;
|
||||
}
|
||||
if (ip == -1) {
|
||||
if (certs.p[i].cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
|
||||
for (cur = &certs.p[i].cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_DNS_NAME &&
|
||||
SlicesEqualCase(host, size, cur->buf.p, cur->buf.len)) {
|
||||
if (!TlsRouteCertificate(ssl, i, host, size)) rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (name = &certs.p[i].cert->subject; name; name = name->next) {
|
||||
if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) &&
|
||||
SlicesEqualCase(host, size, name->val.p, name->val.len)) {
|
||||
if (!TlsRouteCertificate(ssl, i, host, size)) rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (certs.p[i].cert->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
|
||||
for (cur = &certs.p[i].cert->subject_alt_names; cur; cur = cur->next) {
|
||||
if ((cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) ==
|
||||
MBEDTLS_X509_SAN_IP_ADDRESS &&
|
||||
cur->buf.len == 4 && ip == READ32BE(cur->buf.p)) {
|
||||
if (!TlsRouteCertificate(ssl, i, host, size)) rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ok1 = TlsRouteFind(MBEDTLS_PK_ECKEY, ssl, host, size, ip);
|
||||
ok2 = TlsRouteFind(MBEDTLS_PK_RSA, ssl, host, size, ip);
|
||||
if (!ok1 && !ok2) {
|
||||
VERBOSEF("TlsRoute(%`'.*s) not found", size, host);
|
||||
ok1 = TlsRouteFirst(MBEDTLS_PK_ECKEY, ssl);
|
||||
ok2 = TlsRouteFirst(MBEDTLS_PK_RSA, ssl);
|
||||
}
|
||||
if (rc) VERBOSEF("TlsRoute(%`'.*s) not found", size, host);
|
||||
return rc;
|
||||
return ok1 || ok2 ? 0 : -1;
|
||||
}
|
||||
|
||||
static bool TlsSetup(void) {
|
||||
|
@ -1872,19 +1866,19 @@ static void LoadCertificates(void) {
|
|||
certs.p[i].cert, MBEDTLS_OID_SERVER_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH))) {
|
||||
LogCertificate("using server certificate", certs.p[i].cert);
|
||||
UseCertificate(&conf, certs.p + i);
|
||||
UseCertificate(&conf, certs.p + i, "server");
|
||||
havecert = true;
|
||||
}
|
||||
if (!mbedtls_x509_crt_check_extended_key_usage(
|
||||
certs.p[i].cert, MBEDTLS_OID_CLIENT_AUTH,
|
||||
MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH))) {
|
||||
LogCertificate("using client certificate", certs.p[i].cert);
|
||||
UseCertificate(&confcli, certs.p + i);
|
||||
UseCertificate(&confcli, certs.p + i, "client");
|
||||
haveclientcert = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!havecert || !haveclientcert) {
|
||||
if (!havecert) {
|
||||
if ((ksk = GetKeySigningKey()).key) {
|
||||
DEBUGF("generating ssl certificates using %`'s",
|
||||
gc(FormatX509Name(&ksk.cert->subject)));
|
||||
|
@ -1898,14 +1892,14 @@ static void LoadCertificates(void) {
|
|||
}
|
||||
#ifdef MBEDTLS_ECP_C
|
||||
ecp = GenerateEcpCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &ecp);
|
||||
if (!haveclientcert) UseCertificate(&confcli, &ecp);
|
||||
if (!havecert) UseCertificate(&conf, &ecp, "server");
|
||||
if (!haveclientcert && ksk.key) UseCertificate(&confcli, &ecp, "client");
|
||||
AppendCert(ecp.cert, ecp.key);
|
||||
#endif
|
||||
#ifdef MBEDTLS_RSA_C
|
||||
rsa = GenerateRsaCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &rsa);
|
||||
if (!haveclientcert) UseCertificate(&confcli, &rsa);
|
||||
if (!havecert) UseCertificate(&conf, &rsa, "server");
|
||||
if (!haveclientcert && ksk.key) UseCertificate(&confcli, &rsa, "client");
|
||||
AppendCert(rsa.cert, rsa.key);
|
||||
#endif
|
||||
}
|
||||
|
@ -2409,11 +2403,12 @@ static void AppendLogo(void) {
|
|||
char *p, *q;
|
||||
struct Asset *a;
|
||||
if ((a = GetAsset("/redbean.png", 12)) && (p = LoadAsset(a, &n))) {
|
||||
q = EncodeBase64(p, n, &n);
|
||||
Append("<img alt=\"[logo]\" src=\"data:image/png;base64,");
|
||||
AppendData(q, n);
|
||||
Append("\">\r\n");
|
||||
free(q);
|
||||
if ((q = EncodeBase64(p, n, &n))) {
|
||||
appends(&outbuf, "<img alt=\"[logo]\" src=\"data:image/png;base64,");
|
||||
appendd(&outbuf, q, n);
|
||||
appends(&outbuf, "\">\r\n");
|
||||
free(q);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
@ -2438,15 +2433,17 @@ static ssize_t Send(struct iovec *iov, int iovlen) {
|
|||
|
||||
static char *CommitOutput(char *p) {
|
||||
uint32_t crc;
|
||||
size_t outbuflen;
|
||||
if (!contentlength) {
|
||||
if (istext && outbuf.n >= 100) {
|
||||
outbuflen = appendz(outbuf).i;
|
||||
if (istext && outbuflen >= 100) {
|
||||
p = stpcpy(p, "Vary: Accept-Encoding\r\n");
|
||||
if (!IsTiny() && ClientAcceptsGzip()) {
|
||||
gzipped = true;
|
||||
crc = crc32_z(0, outbuf.p, outbuf.n);
|
||||
crc = crc32_z(0, outbuf, outbuflen);
|
||||
WRITE32LE(gzip_footer + 0, crc);
|
||||
WRITE32LE(gzip_footer + 4, outbuf.n);
|
||||
content = FreeLater(Deflate(outbuf.p, outbuf.n, &contentlength));
|
||||
WRITE32LE(gzip_footer + 4, outbuflen);
|
||||
content = FreeLater(Deflate(outbuf, outbuflen, &contentlength));
|
||||
DropOutput();
|
||||
} else {
|
||||
UseOutput();
|
||||
|
@ -2463,11 +2460,11 @@ static char *CommitOutput(char *p) {
|
|||
static char *ServeDefaultErrorPage(char *p, unsigned code, const char *reason) {
|
||||
p = AppendContentType(p, "text/html; charset=ISO-8859-1");
|
||||
reason = FreeLater(EscapeHtml(reason, -1, 0));
|
||||
Append("\
|
||||
appends(&outbuf, "\
|
||||
<!doctype html>\r\n\
|
||||
<title>");
|
||||
Append("%d %s", code, reason);
|
||||
Append("\
|
||||
appendf(&outbuf, "%d %s", code, reason);
|
||||
appendf(&outbuf, "\
|
||||
</title>\r\n\
|
||||
<style>\r\n\
|
||||
html { color: #111; font-family: sans-serif; }\r\n\
|
||||
|
@ -2475,8 +2472,8 @@ img { vertical-align: middle; }\r\n\
|
|||
</style>\r\n\
|
||||
<h1>\r\n");
|
||||
AppendLogo();
|
||||
Append("%d %s\r\n", code, reason);
|
||||
Append("</h1>\r\n");
|
||||
appendf(&outbuf, "%d %s\r\n", code, reason);
|
||||
appends(&outbuf, "</h1>\r\n");
|
||||
UseOutput();
|
||||
return p;
|
||||
}
|
||||
|
@ -2486,7 +2483,7 @@ static char *ServeErrorImpl(unsigned code, const char *reason) {
|
|||
char *p, *s;
|
||||
struct Asset *a;
|
||||
LockInc(&shared->c.errors);
|
||||
ClearOutput();
|
||||
DropOutput();
|
||||
p = SetStatus(code, reason);
|
||||
s = xasprintf("/%d.html", code);
|
||||
a = GetAsset(s, strlen(s));
|
||||
|
@ -2868,7 +2865,7 @@ static char *ServeListing(void) {
|
|||
size_t i, n, pathlen, rn[6];
|
||||
LockInc(&shared->c.listingrequests);
|
||||
if (msg.method != kHttpGet && msg.method != kHttpHead) return BadMethod();
|
||||
Append("\
|
||||
appends(&outbuf, "\
|
||||
<!doctype html>\r\n\
|
||||
<meta charset=\"utf-8\">\r\n\
|
||||
<title>redbean zip listing</title>\r\n\
|
||||
|
@ -2885,15 +2882,16 @@ td { padding-right: 3em; }\r\n\
|
|||
<header><h1>\r\n");
|
||||
AppendLogo();
|
||||
rp[0] = EscapeHtml(brand, -1, &rn[0]);
|
||||
AppendData(rp[0], rn[0]);
|
||||
appendd(&outbuf, rp[0], rn[0]);
|
||||
free(rp[0]);
|
||||
Append("</h1>\r\n"
|
||||
"<div class=\"eocdcomment\">%.*s</div>\r\n"
|
||||
"<hr>\r\n"
|
||||
"</header>\r\n"
|
||||
"<pre>\r\n",
|
||||
strnlen(GetZipCdirComment(zcdir), GetZipCdirCommentSize(zcdir)),
|
||||
GetZipCdirComment(zcdir));
|
||||
appendf(&outbuf,
|
||||
"</h1>\r\n"
|
||||
"<div class=\"eocdcomment\">%.*s</div>\r\n"
|
||||
"<hr>\r\n"
|
||||
"</header>\r\n"
|
||||
"<pre>\r\n",
|
||||
strnlen(GetZipCdirComment(zcdir), GetZipCdirCommentSize(zcdir)),
|
||||
GetZipCdirComment(zcdir));
|
||||
memset(w, 0, sizeof(w));
|
||||
n = GetZipCdirRecords(zcdir);
|
||||
for (zcf = zbase + GetZipCdirOffset(zcdir); n--;
|
||||
|
@ -2925,14 +2923,16 @@ td { padding-right: 3em; }\r\n\
|
|||
iso8601(tb, &tm);
|
||||
if (IsCompressionMethodSupported(ZIP_CFILE_COMPRESSIONMETHOD(zcf)) &&
|
||||
IsAcceptablePath(path, pathlen)) {
|
||||
Append("<a href=\"%.*s\">%-*.*s</a> %s %0*o %4s %,*ld %'s\r\n",
|
||||
rn[2], rp[2], w[0], rn[4], rp[4], tb, w[1], GetZipCfileMode(zcf),
|
||||
DescribeCompressionRatio(rb, zcf), w[2],
|
||||
GetZipCfileUncompressedSize(zcf), rp[3]);
|
||||
appendf(&outbuf,
|
||||
"<a href=\"%.*s\">%-*.*s</a> %s %0*o %4s %,*ld %'s\r\n",
|
||||
rn[2], rp[2], w[0], rn[4], rp[4], tb, w[1],
|
||||
GetZipCfileMode(zcf), DescribeCompressionRatio(rb, zcf), w[2],
|
||||
GetZipCfileUncompressedSize(zcf), rp[3]);
|
||||
} else {
|
||||
Append("%-*.*s %s %0*o %4s %,*ld %'s\r\n", w[0], rn[4], rp[4], tb,
|
||||
w[1], GetZipCfileMode(zcf), DescribeCompressionRatio(rb, zcf),
|
||||
w[2], GetZipCfileUncompressedSize(zcf), rp[3]);
|
||||
appendf(&outbuf, "%-*.*s %s %0*o %4s %,*ld %'s\r\n", w[0], rn[4],
|
||||
rp[4], tb, w[1], GetZipCfileMode(zcf),
|
||||
DescribeCompressionRatio(rb, zcf), w[2],
|
||||
GetZipCfileUncompressedSize(zcf), rp[3]);
|
||||
}
|
||||
free(rp[4]);
|
||||
free(rp[3]);
|
||||
|
@ -2942,42 +2942,44 @@ td { padding-right: 3em; }\r\n\
|
|||
}
|
||||
free(path);
|
||||
}
|
||||
Append("</pre><footer><hr>\r\n");
|
||||
Append("<table border=\"0\"><tr>\r\n");
|
||||
Append("<td valign=\"top\">\r\n");
|
||||
Append("<a href=\"/statusz\">/statusz</a>\r\n");
|
||||
appends(&outbuf, "\
|
||||
</pre><footer><hr>\r\n\
|
||||
<table border=\"0\"><tr>\r\n\
|
||||
<td valign=\"top\">\r\n\
|
||||
<a href=\"/statusz\">/statusz</a>\r\n\
|
||||
");
|
||||
if (shared->c.connectionshandled) {
|
||||
Append("says your redbean<br>\r\n");
|
||||
AppendResourceReport(&shared->children, "<br>\r\n");
|
||||
appends(&outbuf, "says your redbean<br>\r\n");
|
||||
AppendResourceReport(&outbuf, &shared->children, "<br>\r\n");
|
||||
}
|
||||
Append("<td valign=\"top\">\r\n");
|
||||
appends(&outbuf, "<td valign=\"top\">\r\n");
|
||||
and = "";
|
||||
x = nowl() - startserver;
|
||||
y = ldiv(x, 24L * 60 * 60);
|
||||
if (y.quot) {
|
||||
Append("%,ld day%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%,ld day%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
and = "and ";
|
||||
}
|
||||
y = ldiv(y.rem, 60 * 60);
|
||||
if (y.quot) {
|
||||
Append("%,ld hour%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%,ld hour%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
and = "and ";
|
||||
}
|
||||
y = ldiv(y.rem, 60);
|
||||
if (y.quot) {
|
||||
Append("%,ld minute%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%,ld minute%s ", y.quot, y.quot == 1 ? "" : "s");
|
||||
and = "and ";
|
||||
}
|
||||
Append("%s%,ld second%s of operation<br>\r\n", and, y.rem,
|
||||
y.rem == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%s%,ld second%s of operation<br>\r\n", and, y.rem,
|
||||
y.rem == 1 ? "" : "s");
|
||||
x = shared->c.messageshandled;
|
||||
Append("%,ld message%s handled<br>\r\n", x, x == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%,ld message%s handled<br>\r\n", x, x == 1 ? "" : "s");
|
||||
x = shared->c.connectionshandled;
|
||||
Append("%,ld connection%s handled<br>\r\n", x, x == 1 ? "" : "s");
|
||||
appendf(&outbuf, "%,ld connection%s handled<br>\r\n", x, x == 1 ? "" : "s");
|
||||
x = shared->workers;
|
||||
Append("%,ld connection%s active<br>\r\n", x, x == 1 ? "" : "s");
|
||||
Append("</table>\r\n");
|
||||
Append("</footer>\r\n");
|
||||
appendf(&outbuf, "%,ld connection%s active<br>\r\n", x, x == 1 ? "" : "s");
|
||||
appends(&outbuf, "</table>\r\n");
|
||||
appends(&outbuf, "</footer>\r\n");
|
||||
p = SetStatus(200, "OK");
|
||||
p = AppendContentType(p, "text/html");
|
||||
p = AppendCache(p, 0);
|
||||
|
@ -2989,11 +2991,11 @@ static const char *MergeNames(const char *a, const char *b) {
|
|||
}
|
||||
|
||||
static void AppendLong1(const char *a, long x) {
|
||||
if (x) Append("%s: %ld\r\n", a, x);
|
||||
if (x) appendf(&outbuf, "%s: %ld\r\n", a, x);
|
||||
}
|
||||
|
||||
static void AppendLong2(const char *a, const char *b, long x) {
|
||||
if (x) Append("%s.%s: %ld\r\n", a, b, x);
|
||||
if (x) appendf(&outbuf, "%s.%s: %ld\r\n", a, b, x);
|
||||
}
|
||||
|
||||
static void AppendTimeval(const char *a, struct timeval *tv) {
|
||||
|
@ -3687,6 +3689,7 @@ static void LogBody(const char *d, const char *s, size_t n) {
|
|||
}
|
||||
|
||||
static int LuaFetch(lua_State *L) {
|
||||
#define ssl nope /* TODO(jart): make this file less huge */
|
||||
char *p;
|
||||
ssize_t rc;
|
||||
bool usessl;
|
||||
|
@ -3843,7 +3846,7 @@ static int LuaFetch(lua_State *L) {
|
|||
bio->b = 0;
|
||||
bio->c = -1;
|
||||
mbedtls_ssl_set_bio(&sslcli, bio, TlsSend, 0, TlsRecvImpl);
|
||||
while ((ret = mbedtls_ssl_handshake(&ssl))) {
|
||||
while ((ret = mbedtls_ssl_handshake(&sslcli))) {
|
||||
switch (ret) {
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:
|
||||
break;
|
||||
|
@ -3856,7 +3859,8 @@ static int LuaFetch(lua_State *L) {
|
|||
}
|
||||
LockInc(&shared->c.sslhandshakes);
|
||||
VERBOSEF("SHAKEN %s:%s %s %s", host, port,
|
||||
mbedtls_ssl_get_ciphersuite(&ssl), mbedtls_ssl_get_version(&ssl));
|
||||
mbedtls_ssl_get_ciphersuite(&sslcli),
|
||||
mbedtls_ssl_get_version(&sslcli));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4003,13 +4007,13 @@ static int LuaFetch(lua_State *L) {
|
|||
|
||||
Finished:
|
||||
if (paylen && logbodies) LogBody("received", inbuf.p + hdrsize, paylen);
|
||||
LOGF("FETCH %s HTTP%02d %d %s %`'.*s", method, msg.version, msg.status, urlarg,
|
||||
HeaderLength(kHttpServer), HeaderData(kHttpServer));
|
||||
LOGF("FETCH %s HTTP%02d %d %s %`'.*s", method, msg.version, msg.status,
|
||||
urlarg, HeaderLength(kHttpServer), HeaderData(kHttpServer));
|
||||
if (followredirect && HasHeader(kHttpLocation) &&
|
||||
(msg.status == 301 || msg.status == 308 || // permanent redirects
|
||||
msg.status == 302 || msg.status == 307 || // temporary redirects
|
||||
msg.status == 303 // see other; non-GET changes to GET, body lost
|
||||
) && numredirects < maxredirects) {
|
||||
(msg.status == 301 || msg.status == 308 || // permanent redirects
|
||||
msg.status == 302 || msg.status == 307 || // temporary redirects
|
||||
msg.status == 303 /* see other; non-GET changes to GET, body lost */) &&
|
||||
numredirects < maxredirects) {
|
||||
// if 303, then remove body and set method to GET
|
||||
if (msg.status == 303) {
|
||||
body = "";
|
||||
|
@ -4018,8 +4022,8 @@ Finished:
|
|||
}
|
||||
// create table if needed
|
||||
if (!lua_istable(L, 2)) {
|
||||
lua_settop(L, 1); // pop body if present
|
||||
lua_createtable(L, 0, 3); // body, method, numredirects
|
||||
lua_settop(L, 1); // pop body if present
|
||||
lua_createtable(L, 0, 3); // body, method, numredirects
|
||||
}
|
||||
lua_pushlstring(L, body, bodylen);
|
||||
lua_setfield(L, -2, "body");
|
||||
|
@ -4058,6 +4062,7 @@ VerifyFailed:
|
|||
LuaThrowTlsError(
|
||||
L, gc(DescribeSslVerifyFailure(sslcli.session_negotiate->verify_result)),
|
||||
ret);
|
||||
#undef ssl
|
||||
}
|
||||
|
||||
static int LuaGetDate(lua_State *L) {
|
||||
|
@ -4496,7 +4501,7 @@ static int LuaWrite(lua_State *L) {
|
|||
const char *data;
|
||||
if (!lua_isnil(L, 1)) {
|
||||
data = luaL_checklstring(L, 1, &size);
|
||||
AppendData(data, size);
|
||||
appendd(&outbuf, data, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -5173,7 +5178,7 @@ static int LuaRe(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static bool LuaRun(const char *path) {
|
||||
static bool LuaRun(const char *path, bool mandatory) {
|
||||
size_t pathlen;
|
||||
struct Asset *a;
|
||||
const char *code;
|
||||
|
@ -5184,7 +5189,11 @@ static bool LuaRun(const char *path) {
|
|||
effectivepath.n = pathlen;
|
||||
DEBUGF("LuaRun(%`'s)", path);
|
||||
if (luaL_dostring(L, code) != LUA_OK) {
|
||||
WARNF("%s %s", path, lua_tostring(L, -1));
|
||||
if (mandatory) {
|
||||
FATALF("%s %s", path, lua_tostring(L, -1));
|
||||
} else {
|
||||
WARNF("%s %s", path, lua_tostring(L, -1));
|
||||
}
|
||||
}
|
||||
free(code);
|
||||
}
|
||||
|
@ -5341,9 +5350,21 @@ static void LuaSetConstant(lua_State *L, const char *s, long x) {
|
|||
lua_setglobal(L, s);
|
||||
}
|
||||
|
||||
static char *GetDefaultLuaPath(void) {
|
||||
char *s;
|
||||
size_t i;
|
||||
for (s = 0, i = 0; i < stagedirs.n; ++i) {
|
||||
appendf(&s, "%s/.lua/?.lua;%s/.lua/?/init.lua;", stagedirs.p[i].s,
|
||||
stagedirs.p[i].s);
|
||||
}
|
||||
appends(&s, "zip:.lua/?.lua;zip:.lua/?/init.lua");
|
||||
return s;
|
||||
}
|
||||
|
||||
static void LuaInit(void) {
|
||||
#ifndef STATIC
|
||||
size_t i;
|
||||
g_lua_path_default = GetDefaultLuaPath();
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
for (i = 0; i < ARRAYLEN(kLuaLibs); ++i) {
|
||||
|
@ -5361,7 +5382,7 @@ static void LuaInit(void) {
|
|||
LuaSetConstant(L, "kLogWarn", kLogWarn);
|
||||
LuaSetConstant(L, "kLogError", kLogError);
|
||||
LuaSetConstant(L, "kLogFatal", kLogFatal);
|
||||
if (LuaRun("/.init.lua")) {
|
||||
if (LuaRun("/.init.lua", true)) {
|
||||
hasonhttprequest = IsHookDefined("OnHttpRequest");
|
||||
hasonclientconnection = IsHookDefined("OnClientConnection");
|
||||
hasonprocesscreate = IsHookDefined("OnProcessCreate");
|
||||
|
@ -5376,7 +5397,7 @@ static void LuaInit(void) {
|
|||
|
||||
static void LuaReload(void) {
|
||||
#ifndef STATIC
|
||||
if (!LuaRun("/.reload.lua")) {
|
||||
if (!LuaRun("/.reload.lua", false)) {
|
||||
DEBUGF("no /.reload.lua defined");
|
||||
}
|
||||
#endif
|
||||
|
@ -5580,7 +5601,7 @@ static void HandleHeartbeat(void) {
|
|||
Reindex();
|
||||
getrusage(RUSAGE_SELF, &shared->server);
|
||||
#ifndef STATIC
|
||||
LuaRun("/.heartbeat.lua");
|
||||
LuaRun("/.heartbeat.lua", false);
|
||||
CollectGarbage();
|
||||
#endif
|
||||
for (i = 0; i < servers.n; ++i) {
|
||||
|
@ -6156,13 +6177,14 @@ static bool HandleMessage(void) {
|
|||
}
|
||||
|
||||
static void InitRequest(void) {
|
||||
assert(!outbuf);
|
||||
frags = 0;
|
||||
outbuf = 0;
|
||||
gzipped = 0;
|
||||
branded = 0;
|
||||
content = 0;
|
||||
msgsize = 0;
|
||||
loops.n = 0;
|
||||
outbuf.n = 0;
|
||||
generator = 0;
|
||||
luaheaderp = 0;
|
||||
contentlength = 0;
|
||||
|
@ -6614,9 +6636,9 @@ static void MemDestroy(void) {
|
|||
Free(&unmaplist.p), unmaplist.n = 0;
|
||||
Free(&freelist.p), freelist.n = 0;
|
||||
Free(&servers.p), servers.n = 0;
|
||||
Free(&outbuf.p), outbuf.n = 0;
|
||||
Free(&hdrbuf.p), hdrbuf.n = 0;
|
||||
Free(&inbuf.p), inbuf.n = 0;
|
||||
Free(&outbuf);
|
||||
FreeStrings(&stagedirs);
|
||||
FreeStrings(&hidepaths);
|
||||
Free(&launchbrowser);
|
||||
|
|
Loading…
Reference in a new issue