FU: Some FastCGI fixes; FU::Util: utf8_decode & URI escaping
This commit is contained in:
parent
d9fba4e8d8
commit
90cfd66069
6 changed files with 146 additions and 33 deletions
42
c/fcgi.c
42
c/fcgi.c
|
|
@ -11,12 +11,15 @@
|
|||
#define FCGI_UNKNOWN_TYPE 11
|
||||
|
||||
#define FUFE_OK 0
|
||||
#define FUFE_EOF -1 /* protocol-level EOF */
|
||||
#define FUFE_EOF -1 /* unexpected protocol-level EOF */
|
||||
#define FUFE_IO -2
|
||||
#define FUFE_PROTO -3
|
||||
#define FUFE_PLEN -4
|
||||
#define FUFE_CLEN -5
|
||||
#define FUFE_ABORT -6 /* explicit abort or client-level EOF */
|
||||
#define FUFE_NOREQ -7 /* protocol-level EOF before we received anything */
|
||||
|
||||
#define FUFCGI_MAX_DATA 65535
|
||||
|
||||
typedef struct {
|
||||
SV *self;
|
||||
|
|
@ -29,7 +32,7 @@ typedef struct {
|
|||
HV *params;
|
||||
|
||||
/* Single buffer for reading & writing, we only do one thing at a time */
|
||||
char buf[8 + 65536 + 256]; /* fits a maximum-length fcgi record */
|
||||
char buf[8 + FUFCGI_MAX_DATA + 255]; /* fits a maximum-length fcgi record */
|
||||
int len; /* total number of bytes in the buffer */
|
||||
int off; /* number of bytes consumed */
|
||||
} fufcgi;
|
||||
|
|
@ -154,7 +157,7 @@ static int fufcgi_read_record(fufcgi *ctx, fufcgi_rec *rec) {
|
|||
rec->type = ctx->buf[ctx->off+1];
|
||||
rec->id = fu_frombeU(16, ctx->buf+ctx->off+2);
|
||||
rec->len = fu_frombeU(16, ctx->buf+ctx->off+4);
|
||||
int pad = ctx->buf[ctx->off+6];
|
||||
int pad = (unsigned char)ctx->buf[ctx->off+6];
|
||||
ctx->off += 8;
|
||||
|
||||
if ((r = fufcgi_fill(ctx, rec->len + pad)) != FUFE_OK) return r;
|
||||
|
|
@ -225,7 +228,7 @@ static int fufcgi_read_req_record(fufcgi *ctx, fufcgi_rec *rec) {
|
|||
int r;
|
||||
char tmp[128]; /* Large enough for a FCGI_GET_VALUES_RESULT */
|
||||
while (1) {
|
||||
if ((r = fufcgi_read_record(ctx, rec)) != FUFE_OK) return r;
|
||||
if ((r = fufcgi_read_record(ctx, rec)) != FUFE_OK) return r == FUFE_EOF && ctx->len == 0 ? FUFE_NOREQ : r;
|
||||
|
||||
switch (rec->type) {
|
||||
case FCGI_PARAMS:
|
||||
|
|
@ -405,23 +408,40 @@ static int fufcgi_read_req(pTHX_ fufcgi *ctx, SV *headers, SV *params) {
|
|||
|
||||
static void fufcgi_flush(fufcgi *ctx) {
|
||||
fufcgi_rec hdr;
|
||||
if (ctx->off > 8) {
|
||||
hdr.len = ctx->off - 8;
|
||||
if (ctx->len > 0) {
|
||||
hdr.len = ctx->len;
|
||||
hdr.type = FCGI_STDOUT;
|
||||
hdr.id = ctx->reqid;
|
||||
fufcgi_write_record(ctx, &hdr, ctx->buf);
|
||||
ctx->off = 8;
|
||||
ctx->len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void fufcgi_print(fufcgi *ctx, const char *buf, int len) {
|
||||
int r;
|
||||
while (len > 0) {
|
||||
r = len > 65535 - ctx->off ? 65535 - ctx->off : len;
|
||||
memcpy(ctx->buf+ctx->off, buf, r);
|
||||
ctx->off += r;
|
||||
r = len > FUFCGI_MAX_DATA - ctx->len ? FUFCGI_MAX_DATA - ctx->len : len;
|
||||
memcpy(ctx->buf+8+ctx->len, buf, r);
|
||||
ctx->len += r;
|
||||
len -= r;
|
||||
buf += r;
|
||||
if (ctx->off >= 65535) fufcgi_flush(ctx);
|
||||
if (ctx->len >= FUFCGI_MAX_DATA) fufcgi_flush(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void fufcgi_done(fufcgi *ctx) {
|
||||
fufcgi_rec hdr;
|
||||
fufcgi_flush(ctx);
|
||||
|
||||
hdr.len = 0;
|
||||
hdr.type = FCGI_STDOUT;
|
||||
hdr.id = ctx->reqid;
|
||||
fufcgi_write_record(ctx, &hdr, ctx->buf);
|
||||
|
||||
memcpy(ctx->buf+8, "\0\0\0\0\0\0\0\0", 8); /* FCGI_REQUEST_COMPLETE */
|
||||
hdr.type = FCGI_END_REQUEST;
|
||||
hdr.len = 8;
|
||||
fufcgi_write_record(ctx, &hdr, ctx->buf);
|
||||
|
||||
ctx->reqid = ctx->len = ctx->off = 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue