Commit 48bac014 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

More http->failed infusion and associated cleanups.

parent 47d66bb4
...@@ -987,15 +987,14 @@ struct http *HTTP_create(void *p, uint16_t nhttp); ...@@ -987,15 +987,14 @@ struct http *HTTP_create(void *p, uint16_t nhttp);
const char *http_StatusMessage(unsigned); const char *http_StatusMessage(unsigned);
unsigned http_EstimateWS(const struct http *fm, unsigned how, uint16_t *nhd); unsigned http_EstimateWS(const struct http *fm, unsigned how, uint16_t *nhd);
void HTTP_Init(void); void HTTP_Init(void);
void http_ClrHeader(struct http *to);
void http_SetResp(struct http *to, const char *proto, uint16_t status, void http_SetResp(struct http *to, const char *proto, uint16_t status,
const char *response); const char *response);
void http_FilterReq(struct http *to, const struct http *fm, unsigned how); void http_FilterReq(struct http *to, const struct http *fm, unsigned how);
void http_FilterResp(const struct http *fm, struct http *to, unsigned how); void http_FilterResp(const struct http *fm, struct http *to, unsigned how);
void http_PutProtocol(const struct http *to, const char *protocol); void http_PutProtocol(struct http *to, const char *protocol);
void http_PutStatus(struct http *to, uint16_t status); void http_PutStatus(struct http *to, uint16_t status);
void http_ForceHeader(struct http *to, const char *hdr, const char *val); void http_ForceHeader(struct http *to, const char *hdr, const char *val);
void http_PutResponse(const struct http *to, const char *response); void http_PutResponse(struct http *to, const char *response);
void http_PrintfHeader(struct http *to, const char *fmt, ...) void http_PrintfHeader(struct http *to, const char *fmt, ...)
__printflike(2, 3); __printflike(2, 3);
void http_SetHeader(struct http *to, const char *hdr); void http_SetHeader(struct http *to, const char *hdr);
...@@ -1014,7 +1013,7 @@ const char *http_GetReq(const struct http *hp); ...@@ -1014,7 +1013,7 @@ const char *http_GetReq(const struct http *hp);
int http_HdrIs(const struct http *hp, const char *hdr, const char *val); int http_HdrIs(const struct http *hp, const char *hdr, const char *val);
int http_IsHdr(const txt *hh, const char *hdr); int http_IsHdr(const txt *hh, const char *hdr);
enum sess_close http_DoConnection(const struct http *); enum sess_close http_DoConnection(const struct http *);
void http_CopyHome(const struct http *hp); void http_CopyHome(struct http *hp);
void http_Unset(struct http *hp, const char *hdr); void http_Unset(struct http *hp, const char *hdr);
void http_CollectHdr(struct http *hp, const char *hdr); void http_CollectHdr(struct http *hp, const char *hdr);
void http_VSL_log(const struct http *hp); void http_VSL_log(const struct http *hp);
......
...@@ -97,6 +97,8 @@ http_VSL_log(const struct http *hp) ...@@ -97,6 +97,8 @@ http_VSL_log(const struct http *hp)
static void static void
http_fail(struct http *hp) http_fail(struct http *hp)
{ {
VSC_C_main->losthdr++;
VSLb(hp->vsl, SLT_Error, "out of workspace"); VSLb(hp->vsl, SLT_Error, "out of workspace");
hp->failed = 1; hp->failed = 1;
} }
...@@ -178,6 +180,19 @@ http_Teardown(struct http *hp) ...@@ -178,6 +180,19 @@ http_Teardown(struct http *hp)
memset(hp->hdf, 0, sizeof *hp->hdf * hp->shd); memset(hp->hdf, 0, sizeof *hp->hdf * hp->shd);
} }
/*--------------------------------------------------------------------*/
void
HTTP_Copy(struct http *to, const struct http * const fm)
{
assert(fm->nhd <= to->shd);
memcpy(&to->nhd, &fm->nhd, sizeof *to - offsetof(struct http, nhd));
memcpy(to->hd, fm->hd, fm->nhd * sizeof *to->hd);
memcpy(to->hdf, fm->hdf, fm->nhd * sizeof *to->hdf);
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
int int
...@@ -237,8 +252,10 @@ http_CollectHdr(struct http *hp, const char *hdr) ...@@ -237,8 +252,10 @@ http_CollectHdr(struct http *hp, const char *hdr)
for (d = u = f + 1; u < hp->nhd; u++) { for (d = u = f + 1; u < hp->nhd; u++) {
Tcheck(hp->hd[u]); Tcheck(hp->hd[u]);
if (!http_IsHdr(&hp->hd[u], hdr)) { if (!http_IsHdr(&hp->hd[u], hdr)) {
if (d != u) if (d != u) {
hp->hd[d] = hp->hd[u]; hp->hd[d] = hp->hd[u];
hp->hdf[d] = hp->hdf[u];
}
d++; d++;
continue; continue;
} }
...@@ -250,6 +267,7 @@ http_CollectHdr(struct http *hp, const char *hdr) ...@@ -250,6 +267,7 @@ http_CollectHdr(struct http *hp, const char *hdr)
x = Tlen(hp->hd[f]); x = Tlen(hp->hd[f]);
if (b + x >= e) { if (b + x >= e) {
http_fail(hp); http_fail(hp);
VSLb(hp->vsl, SLT_LostHeader, "%s", hdr + 1);
WS_Release(hp->ws, 0); WS_Release(hp->ws, 0);
return; return;
} }
...@@ -266,6 +284,7 @@ http_CollectHdr(struct http *hp, const char *hdr) ...@@ -266,6 +284,7 @@ http_CollectHdr(struct http *hp, const char *hdr)
x = Tlen(hp->hd[u]) - l; x = Tlen(hp->hd[u]) - l;
if (b + x >= e) { if (b + x >= e) {
http_fail(hp); http_fail(hp);
VSLb(hp->vsl, SLT_LostHeader, "%s", hdr + 1);
WS_Release(hp->ws, 0); WS_Release(hp->ws, 0);
return; return;
} }
...@@ -520,17 +539,6 @@ http_SetH(const struct http *to, unsigned n, const char *fm) ...@@ -520,17 +539,6 @@ http_SetH(const struct http *to, unsigned n, const char *fm)
http_VSLH(to, n); http_VSLH(to, n);
} }
static void
http_linkh(const struct http *to, const struct http *fm, unsigned n)
{
assert(n < HTTP_HDR_FIRST);
Tcheck(fm->hd[n]);
to->hd[n] = fm->hd[n];
to->hdf[n] = fm->hdf[n];
http_VSLH(to, n);
}
void void
http_ForceGet(const struct http *to) http_ForceGet(const struct http *to)
{ {
...@@ -596,26 +604,35 @@ http_filterfields(struct http *to, const struct http *fm, unsigned how) ...@@ -596,26 +604,35 @@ http_filterfields(struct http *to, const struct http *fm, unsigned how)
continue; continue;
if (fm->hdf[u] & HDF_FILTER) if (fm->hdf[u] & HDF_FILTER)
continue; continue;
Tcheck(fm->hd[u]);
#define HTTPH(a, b, c) \ #define HTTPH(a, b, c) \
if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \ if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
continue; continue;
#include "tbl/http_headers.h" #include "tbl/http_headers.h"
#undef HTTPH #undef HTTPH
Tcheck(fm->hd[u]); assert (to->nhd < to->shd);
if (to->nhd < to->shd) {
to->hd[to->nhd] = fm->hd[u]; to->hd[to->nhd] = fm->hd[u];
to->hdf[to->nhd] = 0; to->hdf[to->nhd] = 0;
http_VSLH(to, to->nhd); http_VSLH(to, to->nhd);
to->nhd++; to->nhd++;
} else {
VSC_C_main->losthdr++;
VSLbt(to->vsl, SLT_LostHeader, fm->hd[u]);
}
} }
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void
http_linkh(const struct http *to, const struct http *fm, unsigned n)
{
assert(n < HTTP_HDR_FIRST);
Tcheck(fm->hd[n]);
to->hd[n] = fm->hd[n];
to->hdf[n] = fm->hdf[n];
http_VSLH(to, n);
}
/*--------------------------------------------------------------------*/
void void
http_FilterReq(struct http *to, const struct http *fm, unsigned how) http_FilterReq(struct http *to, const struct http *fm, unsigned how)
{ {
...@@ -689,7 +706,7 @@ http_Merge(const struct http *fm, struct http *to, int not_ce) ...@@ -689,7 +706,7 @@ http_Merge(const struct http *fm, struct http *to, int not_ce)
*/ */
void void
http_CopyHome(const struct http *hp) http_CopyHome(struct http *hp)
{ {
unsigned u, l; unsigned u, l;
char *p; char *p;
...@@ -697,48 +714,31 @@ http_CopyHome(const struct http *hp) ...@@ -697,48 +714,31 @@ http_CopyHome(const struct http *hp)
for (u = 0; u < hp->nhd; u++) { for (u = 0; u < hp->nhd; u++) {
if (hp->hd[u].b == NULL) if (hp->hd[u].b == NULL)
continue; continue;
if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e) { if (hp->hd[u].b >= hp->ws->s && hp->hd[u].e <= hp->ws->e)
continue; continue;
}
l = Tlen(hp->hd[u]); l = Tlen(hp->hd[u]);
p = WS_Copy(hp->ws, hp->hd[u].b, l + 1L); p = WS_Copy(hp->ws, hp->hd[u].b, l + 1L);
if (p != NULL) { if (p == NULL) {
http_fail(hp);
VSLb(hp->vsl, SLT_LostHeader, "%s", hp->hd[u].b);
return;
}
hp->hd[u].b = p; hp->hd[u].b = p;
hp->hd[u].e = p + l; hp->hd[u].e = p + l;
} else {
/* XXX This leaves a slot empty */
VSC_C_main->losthdr++;
VSLbt(hp->vsl, SLT_LostHeader, hp->hd[u]);
hp->hd[u].b = NULL;
hp->hd[u].e = NULL;
}
} }
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
void
http_ClrHeader(struct http *to)
{
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
to->nhd = HTTP_HDR_FIRST;
to->status = 0;
to->protover = 0;
to->conds = 0;
memset(to->hd, 0, sizeof *to->hd * to->shd);
}
/*--------------------------------------------------------------------*/
void void
http_SetHeader(struct http *to, const char *hdr) http_SetHeader(struct http *to, const char *hdr)
{ {
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
if (to->nhd >= to->shd) { if (to->nhd >= to->shd) {
VSC_C_main->losthdr++;
VSLb(to->vsl, SLT_LostHeader, "%s", hdr); VSLb(to->vsl, SLT_LostHeader, "%s", hdr);
http_fail(to);
return; return;
} }
http_SetH(to, to->nhd++, hdr); http_SetH(to, to->nhd++, hdr);
...@@ -760,32 +760,29 @@ http_ForceHeader(struct http *to, const char *hdr, const char *val) ...@@ -760,32 +760,29 @@ http_ForceHeader(struct http *to, const char *hdr, const char *val)
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void static void
http_PutField(const struct http *to, int field, const char *string) http_PutField(struct http *to, int field, const char *string)
{ {
char *p; char *p;
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
p = WS_Copy(to->ws, string, -1); p = WS_Copy(to->ws, string, -1);
if (p == NULL) { if (p == NULL) {
http_fail(to);
VSLb(to->vsl, SLT_LostHeader, "%s", string); VSLb(to->vsl, SLT_LostHeader, "%s", string);
to->hd[field].b = NULL; return;
to->hd[field].e = NULL; }
to->hdf[field] = 0;
} else {
to->hd[field].b = p; to->hd[field].b = p;
to->hd[field].e = strchr(p, '\0'); to->hd[field].e = strchr(p, '\0');
to->hdf[field] = 0; to->hdf[field] = 0;
http_VSLH(to, field); http_VSLH(to, field);
}
} }
void void
http_PutProtocol(const struct http *to, const char *protocol) http_PutProtocol(struct http *to, const char *protocol)
{ {
AN(protocol);
http_PutField(to, HTTP_HDR_PROTO, protocol); http_PutField(to, HTTP_HDR_PROTO, protocol);
if (to->hd[HTTP_HDR_PROTO].b == NULL)
http_SetH(to, HTTP_HDR_PROTO, "HTTP/1.1");
Tcheck(to->hd[HTTP_HDR_PROTO]); Tcheck(to->hd[HTTP_HDR_PROTO]);
} }
...@@ -801,12 +798,11 @@ http_PutStatus(struct http *to, uint16_t status) ...@@ -801,12 +798,11 @@ http_PutStatus(struct http *to, uint16_t status)
} }
void void
http_PutResponse(const struct http *to, const char *response) http_PutResponse(struct http *to, const char *response)
{ {
AN(response);
http_PutField(to, HTTP_HDR_RESPONSE, response); http_PutField(to, HTTP_HDR_RESPONSE, response);
if (to->hd[HTTP_HDR_RESPONSE].b == NULL)
http_SetH(to, HTTP_HDR_RESPONSE, "Lost Response");
Tcheck(to->hd[HTTP_HDR_RESPONSE]); Tcheck(to->hd[HTTP_HDR_RESPONSE]);
} }
...@@ -822,17 +818,17 @@ http_PrintfHeader(struct http *to, const char *fmt, ...) ...@@ -822,17 +818,17 @@ http_PrintfHeader(struct http *to, const char *fmt, ...)
n = vsnprintf(to->ws->f, l, fmt, ap); n = vsnprintf(to->ws->f, l, fmt, ap);
va_end(ap); va_end(ap);
if (n + 1 >= l || to->nhd >= to->shd) { if (n + 1 >= l || to->nhd >= to->shd) {
VSC_C_main->losthdr++; http_fail(to);
VSLb(to->vsl, SLT_LostHeader, "%s", to->ws->f); VSLb(to->vsl, SLT_LostHeader, "%s", to->ws->f);
WS_Release(to->ws, 0); WS_Release(to->ws, 0);
} else { return;
}
to->hd[to->nhd].b = to->ws->f; to->hd[to->nhd].b = to->ws->f;
to->hd[to->nhd].e = to->ws->f + n; to->hd[to->nhd].e = to->ws->f + n;
to->hdf[to->nhd] = 0; to->hdf[to->nhd] = 0;
WS_Release(to->ws, n + 1); WS_Release(to->ws, n + 1);
http_VSLH(to, to->nhd); http_VSLH(to, to->nhd);
to->nhd++; to->nhd++;
}
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -860,22 +856,6 @@ http_Unset(struct http *hp, const char *hdr) ...@@ -860,22 +856,6 @@ http_Unset(struct http *hp, const char *hdr)
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
void
HTTP_Copy(struct http *to, const struct http * const fm)
{
to->conds = fm->conds;
to->logtag = fm->logtag;
to->status = fm->status;
to->protover = fm->protover;
to->nhd = fm->nhd;
assert(fm->nhd <= to->shd);
memcpy(to->hd, fm->hd, fm->nhd * sizeof *to->hd);
memcpy(to->hdf, fm->hdf, fm->nhd * sizeof *to->hdf);
}
/*--------------------------------------------------------------------*/
void void
HTTP_Init(void) HTTP_Init(void)
{ {
......
...@@ -102,8 +102,6 @@ cnt_deliver(struct worker *wrk, struct req *req) ...@@ -102,8 +102,6 @@ cnt_deliver(struct worker *wrk, struct req *req)
EXP_Touch(req->obj->objcore, req->t_prev); EXP_Touch(req->obj->objcore, req->t_prev);
HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod); HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
http_ClrHeader(req->resp);
http_FilterResp(req->obj->http, req->resp, 0); http_FilterResp(req->obj->http, req->resp, 0);
if (req->wrk->stats.cache_hit) if (req->wrk->stats.cache_hit)
...@@ -202,8 +200,6 @@ cnt_synth(struct worker *wrk, struct req *req) ...@@ -202,8 +200,6 @@ cnt_synth(struct worker *wrk, struct req *req)
wrk->stats.s_synth++; wrk->stats.s_synth++;
HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
h = req->resp;
now = W_TIM_real(wrk); now = W_TIM_real(wrk);
VSLb_ts_req(req, "Process", now); VSLb_ts_req(req, "Process", now);
...@@ -211,7 +207,8 @@ cnt_synth(struct worker *wrk, struct req *req) ...@@ -211,7 +207,8 @@ cnt_synth(struct worker *wrk, struct req *req)
if (req->err_code < 100 || req->err_code > 999) if (req->err_code < 100 || req->err_code > 999)
req->err_code = 501; req->err_code = 501;
http_ClrHeader(h); HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
h = req->resp;
http_PutProtocol(h, "HTTP/1.1"); http_PutProtocol(h, "HTTP/1.1");
http_PutStatus(h, req->err_code); http_PutStatus(h, req->err_code);
VTIM_format(now, date); VTIM_format(now, date);
...@@ -235,7 +232,7 @@ cnt_synth(struct worker *wrk, struct req *req) ...@@ -235,7 +232,7 @@ cnt_synth(struct worker *wrk, struct req *req)
AZ(VSB_finish(req->synth_body)); AZ(VSB_finish(req->synth_body));
if (wrk->handling == VCL_RET_RESTART) { if (wrk->handling == VCL_RET_RESTART) {
http_ClrHeader(h); HTTP_Setup(h, req->ws, req->vsl, SLT_RespMethod);
VSB_delete(req->synth_body); VSB_delete(req->synth_body);
req->synth_body = NULL; req->synth_body = NULL;
req->req_step = R_STP_RESTART; req->req_step = R_STP_RESTART;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment