mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 06:48:31 +00:00
Update redbean GetResponseBody to take response compression into account (#561)
This commit is contained in:
parent
e204fc0820
commit
04cd62c319
2 changed files with 22 additions and 8 deletions
|
@ -1067,9 +1067,13 @@ FUNCTIONS
|
||||||
IsPrivateIp or IsLoopbackIp return true. When multiple addresses
|
IsPrivateIp or IsLoopbackIp return true. When multiple addresses
|
||||||
are present in the header, the last/right-most address is used.
|
are present in the header, the last/right-most address is used.
|
||||||
|
|
||||||
GetResponseBody() → str
|
GetResponseBody()
|
||||||
Returns the response message body if present or an empty string.
|
├─→ body:str
|
||||||
Also returns an empty string during streaming.
|
└─→ nil, error:str
|
||||||
|
Returns the (uncompressed) response message body if present or an
|
||||||
|
empty string. May also return a partial or empty string during
|
||||||
|
streaming, as the full content may not be known at the call time.
|
||||||
|
Returns an error when decompression fails.
|
||||||
|
|
||||||
GetClientAddr() → ip:uint32,port:uint16
|
GetClientAddr() → ip:uint32,port:uint16
|
||||||
Returns client socket ip4 address and port, e.g. 0x01020304,31337
|
Returns client socket ip4 address and port, e.g. 0x01020304,31337
|
||||||
|
|
|
@ -356,7 +356,6 @@ typedef ssize_t (*writer_f)(int, struct iovec *, int);
|
||||||
|
|
||||||
struct ClearedPerMessage {
|
struct ClearedPerMessage {
|
||||||
bool istext;
|
bool istext;
|
||||||
bool gzipped;
|
|
||||||
bool branded;
|
bool branded;
|
||||||
bool hascontenttype;
|
bool hascontenttype;
|
||||||
bool gotcachecontrol;
|
bool gotcachecontrol;
|
||||||
|
@ -366,6 +365,7 @@ struct ClearedPerMessage {
|
||||||
int isyielding;
|
int isyielding;
|
||||||
char *outbuf;
|
char *outbuf;
|
||||||
char *content;
|
char *content;
|
||||||
|
size_t gzipped;
|
||||||
size_t contentlength;
|
size_t contentlength;
|
||||||
char *luaheaderp;
|
char *luaheaderp;
|
||||||
const char *referrerpolicy;
|
const char *referrerpolicy;
|
||||||
|
@ -2336,7 +2336,7 @@ static char *CommitOutput(char *p) {
|
||||||
p = stpcpy(p, "Vary: Accept-Encoding\r\n");
|
p = stpcpy(p, "Vary: Accept-Encoding\r\n");
|
||||||
}
|
}
|
||||||
if (!IsTiny() && !IsSslCompressed() && ClientAcceptsGzip()) {
|
if (!IsTiny() && !IsSslCompressed() && ClientAcceptsGzip()) {
|
||||||
cpm.gzipped = true;
|
cpm.gzipped = outbuflen;
|
||||||
crc = crc32_z(0, cpm.outbuf, outbuflen);
|
crc = crc32_z(0, cpm.outbuf, outbuflen);
|
||||||
WRITE32LE(gzip_footer + 0, crc);
|
WRITE32LE(gzip_footer + 0, crc);
|
||||||
WRITE32LE(gzip_footer + 4, outbuflen);
|
WRITE32LE(gzip_footer + 4, outbuflen);
|
||||||
|
@ -2568,7 +2568,7 @@ static char *ServeAssetCompressed(struct Asset *a) {
|
||||||
} else {
|
} else {
|
||||||
dg.z = 65536;
|
dg.z = 65536;
|
||||||
}
|
}
|
||||||
cpm.gzipped = true;
|
cpm.gzipped = -1; // signal generator usage with the exact size unknown
|
||||||
cpm.generator = DeflateGenerator;
|
cpm.generator = DeflateGenerator;
|
||||||
bzero(&dg.s, sizeof(dg.s));
|
bzero(&dg.s, sizeof(dg.s));
|
||||||
CHECK_EQ(Z_OK, deflateInit2(&dg.s, 4, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
|
CHECK_EQ(Z_OK, deflateInit2(&dg.s, 4, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
|
||||||
|
@ -2661,9 +2661,9 @@ static inline char *ServeAssetPrecompressed(struct Asset *a) {
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
DEBUGF("(srvr) ServeAssetPrecompressed()");
|
DEBUGF("(srvr) ServeAssetPrecompressed()");
|
||||||
LockInc(&shared->c.precompressedresponses);
|
LockInc(&shared->c.precompressedresponses);
|
||||||
cpm.gzipped = true;
|
|
||||||
crc = ZIP_CFILE_CRC32(zbase + a->cf);
|
crc = ZIP_CFILE_CRC32(zbase + a->cf);
|
||||||
size = GetZipCfileUncompressedSize(zbase + a->cf);
|
size = GetZipCfileUncompressedSize(zbase + a->cf);
|
||||||
|
cpm.gzipped = size;
|
||||||
WRITE32LE(gzip_footer + 0, crc);
|
WRITE32LE(gzip_footer + 0, crc);
|
||||||
WRITE32LE(gzip_footer + 4, size);
|
WRITE32LE(gzip_footer + 4, size);
|
||||||
return SetStatus(200, "OK");
|
return SetStatus(200, "OK");
|
||||||
|
@ -3988,8 +3988,18 @@ static int LuaGetBody(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int LuaGetResponseBody(lua_State *L) {
|
static int LuaGetResponseBody(lua_State *L) {
|
||||||
|
char *s = "";
|
||||||
|
// response can be gzipped (>0), text (=0), or generator (<0)
|
||||||
|
int size = cpm.gzipped > 0 ? cpm.gzipped // original size
|
||||||
|
: cpm.gzipped == 0 ? cpm.contentlength : 0;
|
||||||
OnlyCallDuringRequest(L, "GetResponseBody");
|
OnlyCallDuringRequest(L, "GetResponseBody");
|
||||||
lua_pushlstring(L, cpm.content, cpm.contentlength);
|
if (cpm.gzipped > 0 &&
|
||||||
|
(!(s = FreeLater(malloc(cpm.gzipped))) ||
|
||||||
|
!Inflate(s, cpm.gzipped, cpm.content, cpm.contentlength))) {
|
||||||
|
return LuaNilError(L, "failed to decompress response");
|
||||||
|
}
|
||||||
|
lua_pushlstring(L, cpm.gzipped > 0 ? s // return decompressed
|
||||||
|
: cpm.gzipped == 0 ? cpm.content : "", size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue