FU
view release on metacpan or search on metacpan
default:
memset(tmp+8, 0, 8);
tmp[8] = rec->type;
rec->type = FCGI_UNKNOWN_TYPE;
rec->len = 8;
rec->id = 0;
if ((r = fufcgi_write_record(ctx, rec, tmp)) != FUFE_OK) return r;
break;
}
}
}
static int fufcgi_read_params(pTHX_ fufcgi *ctx, fufcgi_rec *rec) {
int r;
fufcgi_param p;
p.state = FUFC_INIT;
SV *valsv = NULL;
char *val = NULL;
int valleft = 0;
while (1) {
if ((r = fufcgi_read_req_record(ctx, rec)) != FUFE_OK) return r;
if (rec->type == FCGI_ABORT_REQUEST) return FUFE_OK;
if (rec->type != FCGI_PARAMS) return FUFE_PROTO;
if (rec->len == 0) return p.state != FUFC_INIT || valleft ? FUFE_PROTO : FUFE_OK;
char *buf = rec->data;
char *end = rec->data + rec->len;
while (buf < end) {
if (valleft) {
r = valleft > end - buf ? end - buf : valleft;
if (val) {
memcpy(val, buf, r);
val += r;
}
valleft -= r;
buf += r;
if (val && !valleft) {
*val = 0;
SvCUR_set(valsv, p.vallen);
}
continue;
}
if ((buf = fufcgi_param_parse(&p, buf, end)) == NULL) return FUFE_PLEN;
if (p.state != FUFC_INIT) break;
valsv = NULL;
val = NULL;
valleft = p.vallen;
/* https://www.rfc-editor.org/rfc/rfc3875 */
/* Request header */
if (p.namelen > 5 && memcmp(p.name, "HTTP_", 5) == 0) {
p.namelen -= 5;
p.name += 5;
for (r=0; r<p.namelen; r++)
p.name[r] = p.name[r] == '_' ? '-' : p.name[r] >= 'A' && p.name[r] <= 'Z' ? p.name[r] | 0x20 : p.name[r];
if (!(p.namelen == 14 && memcmp(p.name, "content-length", 14) == 0)
&& !(p.namelen == 12 && memcmp(p.name, "content-type", 12) == 0)) {
valsv = newSV(p.vallen+1);
hv_store(ctx->headers, p.name, p.namelen, valsv, 0);
}
} else if (p.namelen == 14 && memcmp(p.name, "CONTENT_LENGTH", 14) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->headers, "content-length", valsv);
} else if (p.namelen == 12 && memcmp(p.name, "CONTENT_TYPE", 12) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->headers, "content-type", valsv);
} else if (p.namelen == 11 && memcmp(p.name, "REMOTE_ADDR", 11) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->params, "ip", valsv);
} else if (p.namelen == 12 && memcmp(p.name, "QUERY_STRING", 12) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->params, "qs", valsv);
} else if (p.namelen == 14 && memcmp(p.name, "REQUEST_METHOD", 14) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->params, "method", valsv);
/* Not in rfc3875; there's no standardized parameter for the URI,
* but every FastCGI-capable web server includes this one */
} else if (p.namelen == 11 && memcmp(p.name, "REQUEST_URI", 11) == 0) {
valsv = newSV(p.vallen+1);
hv_stores(ctx->params, "path", valsv);
} else { /* ignore */ }
if (valsv) {
SvPOK_only(valsv);
val = SvPVX(valsv);
*val = 0; /* in case vallen = 0 */
}
}
}
}
static int fufcgi_read_req(pTHX_ fufcgi *ctx, SV *headers, SV *params) {
if (ctx->reqid) fu_confess("Invalid attempt to read FastCGI request before finishing the previous one");
fufcgi_rec rec;
int r;
ctx->off = ctx->len = 0;
ctx->headers = (HV *)SvRV(headers);
ctx->params = (HV *)SvRV(params);
if ((r = fufcgi_read_params(aTHX_ ctx, &rec)) != FUFE_OK) return r;
int stdinlen = 0;
SV **contentlength = hv_fetchs(ctx->headers, "content-length", 0);
if (contentlength && *contentlength) {
UV uv = 0;
char *v = SvPV_nolen(*contentlength);
if (*v && !grok_atoUV(v, &uv, NULL)) return FUFE_CLEN;
if (uv >= INT_MAX) return FUFE_CLEN;
stdinlen = uv;
}
SV *sv = newSV(stdinlen+1);
hv_stores(ctx->params, "body", sv);
SvPOK_only(sv);
char *stdinbuf = SvPVX(sv);
int stdinleft = stdinlen;
while (1) {
if (rec.type == FCGI_ABORT_REQUEST) return FUFE_ABORT;
else if (rec.type == FCGI_PARAMS) {
if (rec.len != 0) return FUFE_PROTO;
( run in 0.599 second using v1.01-cache-2.11-cpan-d7f47b0818f )