From: phk Date: Thu, 20 Jul 2006 22:08:43 +0000 (+0000) Subject: Yet another refinement to the way we store and deal with HTTP headers. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5488260bb9b9f8180d4fa5a080e18dfcdca427f1;p=varnish Yet another refinement to the way we store and deal with HTTP headers. Record a triplet of {start, data, end} for all HTTP data items. This represents a regrettable uglification of the sourcecode, but most of it compiles out to constants and the runtime benefits will be worth it. Generate H_FOO magic strings for all the headers we know about. These strings have a length as first char and always ends in ':'. Also genereate H_FOO format strings in VCL compiler. Mandate (with assert) that header references happen using H_FOO strings. Make number of allowed HTTP headers a compile time constant (32) but make the workspace a run-time variable (4096). Introduce new SHM tag for dumping aborted HTTP protocol requests. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@531 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index f3b14071..1742927f 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -17,6 +17,19 @@ #define MAX_IOVS 10 +#define MAX_HTTP_HDRS 32 + +#define HTTP_HDR_REQ 0 +#define HTTP_HDR_URL 1 +#define HTTP_HDR_PROTO 2 +#define HTTP_HDR_STATUS 3 +#define HTTP_HDR_RESPONSE 4 +#define HTTP_HDR_FIRST 5 + +#define HTTP_START 0 +#define HTTP_DATA 1 +#define HTTP_END 2 + struct event_base; struct cli; struct sbuf; @@ -46,21 +59,16 @@ struct http { http_callback_f *callback; void *arg; - char *s; /* start of buffer */ - char *t; /* start of trailing data */ - char *v; /* end of valid bytes */ - char *e; /* end of buffer */ - - char *req; - char *url; - char *proto; - char *status; - char *response; + char *s; /* (S)tart of buffer */ + char *t; /* start of (T)railing data */ + char *v; /* end of (V)alid bytes */ + char *f; /* first (F)ree byte */ + char *e; /* (E)nd of buffer */ unsigned conds; /* If-* headers present */ - - unsigned nhdr; - char **hdr; + + char *hd[MAX_HTTP_HDRS][HTTP_END + 1]; + unsigned nhd; }; /*--------------------------------------------------------------------*/ @@ -287,7 +295,8 @@ void HSH_Deref(struct object *o); void HSH_Init(void); /* cache_http.c */ -void http_Init(struct http *ht, void *space); +void HTTP_Init(void); +void http_Init(struct http *ht, void *space, unsigned len); int http_GetHdr(struct http *hp, const char *hdr, char **ptr); int http_GetHdrField(struct http *hp, const char *hdr, const char *field, char **ptr); int http_GetStatus(struct http *hp); @@ -304,6 +313,9 @@ enum http_build { Build_Reply }; void http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp); +#define HTTPH(a, b, c, d, e, f, g) extern char b[]; +#include "http_headers.h" +#undef HTTPH /* cache_pass.c */ void PassSession(struct worker *w, struct sess *sp); diff --git a/varnish-cache/bin/varnishd/cache_backend.c b/varnish-cache/bin/varnishd/cache_backend.c index fd80dd90..a00881e8 100644 --- a/varnish-cache/bin/varnishd/cache_backend.c +++ b/varnish-cache/bin/varnishd/cache_backend.c @@ -44,7 +44,6 @@ struct vbc_mem { #define VBC_MEM_MAGIC 0x2fd7af01 struct vbe_conn vbe; struct http http; - char *http_hdr; }; /* A backend IP */ @@ -74,12 +73,7 @@ vbe_new_conn(void) { struct vbc_mem *vbcm; - vbcm = calloc( - sizeof *vbcm + - heritage.mem_http_headers * sizeof vbcm->http_hdr + - heritage.mem_http_headerspace + - heritage.mem_workspace, - 1); + vbcm = calloc(sizeof *vbcm + heritage.mem_workspace, 1); if (vbcm == NULL) return (NULL); vbcm->magic = VBC_MEM_MAGIC; @@ -87,7 +81,7 @@ vbe_new_conn(void) vbcm->vbe.magic = VBE_CONN_MAGIC; vbcm->vbe.vbcm = vbcm; vbcm->vbe.http = &vbcm->http; - http_Init(&vbcm->http, (void *)(vbcm + 1)); + http_Init(&vbcm->http, (void *)(vbcm + 1), heritage.mem_workspace); return (&vbcm->vbe); } diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index e7384838..374801ad 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -87,10 +87,11 @@ cnt_done(struct sess *sp) assert(sp->obj == NULL); if (sp->fd < 0) { /* Allready closed */ - } else if (http_GetHdr(sp->http, "Connection", &b) && + } else if (http_GetHdr(sp->http, H_Connection, &b) && !strcmp(b, "close")) { vca_close_session(sp, "Connection header"); - } else if (strcmp(sp->http->proto, "HTTP/1.1")) { + } else if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START], + "HTTP/1.1")) { vca_close_session(sp, "not HTTP/1.1"); } VCL_Rel(sp->vcl); diff --git a/varnish-cache/bin/varnishd/cache_fetch.c b/varnish-cache/bin/varnishd/cache_fetch.c index 6cf3f04e..1d30c53a 100644 --- a/varnish-cache/bin/varnishd/cache_fetch.c +++ b/varnish-cache/bin/varnishd/cache_fetch.c @@ -216,13 +216,13 @@ FetchBody(struct worker *w, struct sess *sp) vc = sp->vbc; hp = sp->bkd_http; - if (http_GetHdr(hp, "Last-Modified", &b)) + if (http_GetHdr(hp, H_Last_Modified, &b)) sp->obj->last_modified = TIM_parse(b); http_BuildSbuf(sp->fd, Build_Reply, w->sb, hp); if (body) { - if (http_GetHdr(hp, "Content-Length", &b)) + if (http_GetHdr(hp, H_Content_Length, &b)) cls = fetch_straight(sp, vc->fd, hp, b); - else if (http_HdrIs(hp, "Transfer-Encoding", "chunked")) + else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) cls = fetch_chunked(sp, vc->fd, hp); else cls = fetch_eof(sp, vc->fd, hp); @@ -233,7 +233,7 @@ FetchBody(struct worker *w, struct sess *sp) sp->obj->header = strdup(sbuf_data(w->sb)); VSL_stats->n_header++; - if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close")) + if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close")) cls = 1; if (cls) diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index 77f91ae3..fb11aa7e 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -46,7 +46,7 @@ HSH_Lookup(struct sess *sp) struct http *h; struct objhead *oh; struct object *o; - char *c; + char *url, *host; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); @@ -77,8 +77,9 @@ HSH_Lookup(struct sess *sp) } else CHECK_OBJ_NOTNULL(w->nobj, OBJECT_MAGIC); - if (!http_GetHdr(h, "Host", &c)) - c = h->url; + url = h->hd[HTTP_HDR_URL][HTTP_START]; + if (!http_GetHdr(h, H_Host, &host)) + host = url; if (sp->obj != NULL) { CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); o = sp->obj; @@ -87,7 +88,7 @@ HSH_Lookup(struct sess *sp) AZ(pthread_mutex_lock(&oh->mtx)); goto were_back; } - oh = hash->lookup(h->url, c, w->nobjhead); + oh = hash->lookup(url, host, w->nobjhead); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); if (oh == w->nobjhead) w->nobjhead = NULL; @@ -108,7 +109,7 @@ HSH_Lookup(struct sess *sp) /* Object banned but not reaped yet */ } else if (o->ttl < sp->t_req) { /* Object expired */ - } else if (BAN_CheckObject(o, h->url)) { + } else if (BAN_CheckObject(o, url)) { o->ttl = 0; VSL(SLT_ExpBan, 0, "%u was banned", o->xid); EXP_TTLchange(o); diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index 889f34c8..dd660afe 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -15,19 +15,28 @@ #include "heritage.h" #include "cache.h" +#define HTTPH(a, b, c, d, e, f, g) char b[] = "*" a ":"; +#include "http_headers.h" +#undef HTTPH + +#define VSLH(a, b, c, d) \ + VSLR((a), (b), (c)->hd[d][HTTP_START], (c)->hd[d][HTTP_END]); + /*--------------------------------------------------------------------*/ void -http_Init(struct http *hp, void *space) +http_Init(struct http *hp, void *space, unsigned len) { char *sp = space; + assert(len > 0); memset(hp, 0, sizeof *hp); hp->magic = HTTP_MAGIC; - hp->hdr = (void *)sp; - sp += heritage.mem_http_headers * sizeof hp->hdr; hp->s = sp; - hp->e = hp->s + heritage.mem_http_headerspace; + hp->t = sp; + hp->v = sp; + hp->f = sp; + hp->e = sp + len; } /*--------------------------------------------------------------------*/ @@ -38,19 +47,29 @@ http_GetHdr(struct http *hp, const char *hdr, char **ptr) unsigned u, l; char *p; - l = strlen(hdr); - for (u = 0; u < hp->nhdr; u++) { - if (strncasecmp(hdr, hp->hdr[u], l)) + l = hdr[0]; + assert(l == strlen(hdr + 1)); + assert(hdr[l] == ':'); + hdr++; + for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { + assert(hp->hd[u][HTTP_START] != NULL); + assert(hp->hd[u][HTTP_END] != NULL); + if (hp->hd[u][HTTP_END] < hp->hd[u][HTTP_START] + l) continue; - p = hp->hdr[u]; - if (p[l] != ':') + if (hp->hd[u][HTTP_START][l-1] != ':') continue; - p += l + 1; - while (isspace(*p)) - p++; - *ptr = p; + if (strncasecmp(hdr, hp->hd[u][HTTP_START], l)) + continue; + if (hp->hd[u][HTTP_DATA] == NULL) { + p = hp->hd[u][HTTP_START] + l; + while (isspace(*p)) + p++; + hp->hd[u][HTTP_DATA] = p; + } + *ptr = hp->hd[u][HTTP_DATA]; return (1); } + *ptr = NULL; return (0); } @@ -153,7 +172,9 @@ int http_GetStatus(struct http *hp) { - return (strtoul(hp->status, NULL /* XXX */, 10)); + assert(hp->hd[HTTP_HDR_STATUS][HTTP_START] != NULL); + return (strtoul(hp->hd[HTTP_HDR_STATUS][HTTP_START], + NULL /* XXX */, 10)); } /*-------------------------------------------------------------------- @@ -169,11 +190,12 @@ http_dissect_hdrs(struct http *hp, int fd, char *p) if (*p == '\r') p++; - hp->nhdr = 0; + hp->nhd = HTTP_HDR_FIRST; hp->conds = 0; r = NULL; /* For FlexeLint */ assert(p < hp->v); /* http_header_complete() guarantees this */ for (; p < hp->v; p = r) { + /* XXX: handle continuation lines */ q = strchr(p, '\n'); assert(q != NULL); r = q + 1; @@ -188,17 +210,17 @@ http_dissect_hdrs(struct http *hp, int fd, char *p) p[2] == '-') hp->conds = 1; - if (hp->nhdr < heritage.mem_http_headers) { - hp->hdr[hp->nhdr++] = p; - VSLR(SLT_Header, fd, p, q); + if (hp->nhd < MAX_HTTP_HDRS) { + hp->hd[hp->nhd][HTTP_START] = p; + hp->hd[hp->nhd][HTTP_END] = q; + VSLH(SLT_Header, fd, hp, hp->nhd); + hp->nhd++; } else { VSL_stats->losthdr++; VSLR(SLT_LostHeader, fd, p, q); } } assert(hp->t <= hp->v); - if (hp->t != r) - printf("hp->t %p r %p\n", hp->t, r); assert(hp->t == r); return (0); } @@ -217,25 +239,27 @@ http_DissectRequest(struct http *hp, int fd) continue; /* First, the request type (GET/HEAD etc) */ - hp->req = p; + hp->hd[HTTP_HDR_REQ][HTTP_START] = p; for (; isalpha(*p); p++) ; - VSLR(SLT_Request, fd, hp->req, p); + hp->hd[HTTP_HDR_REQ][HTTP_END] = p; + VSLH(SLT_Request, fd, hp, HTTP_HDR_REQ); *p++ = '\0'; /* Next find the URI */ while (isspace(*p) && *p != '\n') p++; if (*p == '\n') { - VSLR(SLT_Debug, fd, hp->s, hp->v); + VSLR(SLT_HttpGarbage, fd, hp->s, hp->v); return (400); } - hp->url = p; + hp->hd[HTTP_HDR_URL][HTTP_START] = p; while (!isspace(*p)) p++; - VSLR(SLT_URL, fd, hp->url, p); + hp->hd[HTTP_HDR_URL][HTTP_END] = p; + VSLH(SLT_URL, fd, hp, HTTP_HDR_URL); if (*p == '\n') { - VSLR(SLT_Debug, fd, hp->s, hp->v); + VSLR(SLT_HttpGarbage, fd, hp->s, hp->v); return (400); } *p++ = '\0'; @@ -244,19 +268,20 @@ http_DissectRequest(struct http *hp, int fd) while (isspace(*p) && *p != '\n') p++; if (*p == '\n') { - VSLR(SLT_Debug, fd, hp->s, hp->v); + VSLR(SLT_HttpGarbage, fd, hp->s, hp->v); return (400); } - hp->proto = p; + hp->hd[HTTP_HDR_PROTO][HTTP_START] = p; while (!isspace(*p)) p++; - VSLR(SLT_Protocol, fd, hp->proto, p); + hp->hd[HTTP_HDR_PROTO][HTTP_END] = p; + VSLH(SLT_Protocol, fd, hp, HTTP_HDR_PROTO); if (*p != '\n') *p++ = '\0'; while (isspace(*p) && *p != '\n') p++; if (*p != '\n') { - VSLR(SLT_Debug, fd, hp->s, hp->v); + VSLR(SLT_HttpGarbage, fd, hp->s, hp->v); return (400); } *p++ = '\0'; @@ -278,31 +303,35 @@ http_DissectResponse(struct http *hp, int fd) continue; /* First, protocol */ - hp->proto = p; + hp->hd[HTTP_HDR_PROTO][HTTP_START] = p; while (!isspace(*p)) p++; - VSLR(SLT_Protocol, fd, hp->proto, p); + hp->hd[HTTP_HDR_PROTO][HTTP_END] = p; + VSLH(SLT_Protocol, fd, hp, HTTP_HDR_PROTO); *p++ = '\0'; /* Next find the status */ while (isspace(*p)) p++; - hp->status = p; + hp->hd[HTTP_HDR_STATUS][HTTP_START] = p; while (!isspace(*p)) p++; - VSLR(SLT_Status, fd, hp->status, p); + hp->hd[HTTP_HDR_STATUS][HTTP_END] = p; + VSLH(SLT_Status, fd, hp, HTTP_HDR_STATUS); *p++ = '\0'; /* Next find the response */ while (isspace(*p)) p++; - hp->response = p; + hp->hd[HTTP_HDR_RESPONSE][HTTP_START] = p; while (*p != '\n') p++; - for (q = p; q > hp->response && isspace(q[-1]); q--) + for (q = p; q > hp->hd[HTTP_HDR_RESPONSE][HTTP_START] && + isspace(q[-1]); q--) continue; *q = '\0'; - VSLR(SLT_Response, fd, hp->response, q); + hp->hd[HTTP_HDR_RESPONSE][HTTP_END] = q; + VSLH(SLT_Response, fd, hp, HTTP_HDR_RESPONSE); p++; return (http_dissect_hdrs(hp, fd, p)); @@ -360,7 +389,7 @@ http_read_f(int fd, short event, void *arg) l = hp->e - hp->v; if (l <= 1) { VSL(SLT_HttpError, fd, "Received too much"); - VSLR(SLT_Debug, fd, hp->s, hp->v); + VSLR(SLT_HttpGarbage, fd, hp->s, hp->v); hp->t = NULL; ret = 1; } else { @@ -458,55 +487,47 @@ http_supress(const char *hdr, int flag) void http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp) { - unsigned u, sup; + unsigned u, sup, rr; sbuf_clear(sb); assert(sb != NULL); switch (mode) { - case Build_Reply: - sbuf_cat(sb, hp->proto); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->status); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->response); - sup = 2; - break; - case Build_Pipe: - sbuf_cat(sb, hp->req); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->url); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->proto); - sup = 0; - break; - case Build_Pass: - sbuf_cat(sb, hp->req); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->url); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->proto); - sup = 2; - break; - case Build_Fetch: - sbuf_cat(sb, "GET "); - sbuf_cat(sb, hp->url); - sbuf_cat(sb, " "); - sbuf_cat(sb, hp->proto); - sup = 1; - break; + case Build_Reply: rr = 0; sup = 2; break; + case Build_Pipe: rr = 1; sup = 0; break; + case Build_Pass: rr = 1; sup = 2; break; + case Build_Fetch: rr = 2; sup = 1; break; default: sup = 0; /* for flexelint */ + rr = 0; /* for flexelint */ printf("mode = %d\n", mode); - assert(mode == 1 || mode == 2); + assert(__LINE__ == 0); + } + if (rr == 0) { + sbuf_cat(sb, hp->hd[HTTP_HDR_PROTO][HTTP_START]); + sbuf_cat(sb, " "); + sbuf_cat(sb, hp->hd[HTTP_HDR_STATUS][HTTP_START]); + sbuf_cat(sb, " "); + sbuf_cat(sb, hp->hd[HTTP_HDR_RESPONSE][HTTP_START]); + } else { + if (rr == 2) { + sbuf_cat(sb, "GET "); + } else { + sbuf_cat(sb, hp->hd[HTTP_HDR_REQ][HTTP_START]); + sbuf_cat(sb, " "); + } + sbuf_cat(sb, hp->hd[HTTP_HDR_URL][HTTP_START]); + sbuf_cat(sb, " "); + sbuf_cat(sb, hp->hd[HTTP_HDR_PROTO][HTTP_START]); } + sbuf_cat(sb, "\r\n"); - for (u = 0; u < hp->nhdr; u++) { - if (http_supress(hp->hdr[u], sup)) + for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { + if (http_supress(hp->hd[u][HTTP_START], sup)) continue; if (1) - VSL(SLT_BldHdr, fd, "%s", hp->hdr[u]); - sbuf_cat(sb, hp->hdr[u]); + VSL(SLT_BldHdr, fd, "%s", hp->hd[u][HTTP_START]); + sbuf_cat(sb, hp->hd[u][HTTP_START]); sbuf_cat(sb, "\r\n"); } if (mode != Build_Reply) { @@ -514,3 +535,11 @@ http_BuildSbuf(int fd, enum http_build mode, struct sbuf *sb, struct http *hp) sbuf_finish(sb); } } + +void +HTTP_Init(void) +{ +#define HTTPH(a, b, c, d, e, f, g) b[0] = strlen(b + 1); +#include "http_headers.h" +#undef HTTPH +} diff --git a/varnish-cache/bin/varnishd/cache_main.c b/varnish-cache/bin/varnishd/cache_main.c index 8badc7ab..f95f2aae 100644 --- a/varnish-cache/bin/varnishd/cache_main.c +++ b/varnish-cache/bin/varnishd/cache_main.c @@ -105,6 +105,7 @@ child_main(void) VCL_Init(); VCL_Load(heritage.vcl_file, "boot", NULL); + HTTP_Init(); SES_Init(); VBE_Init(); diff --git a/varnish-cache/bin/varnishd/cache_pass.c b/varnish-cache/bin/varnishd/cache_pass.c index 23530fd2..14c33e9b 100644 --- a/varnish-cache/bin/varnishd/cache_pass.c +++ b/varnish-cache/bin/varnishd/cache_pass.c @@ -152,18 +152,18 @@ PassBody(struct worker *w, struct sess *sp) sbuf_finish(w->sb); RES_Write(sp, sbuf_data(w->sb), sbuf_len(w->sb)); - if (http_GetHdr(hp, "Content-Length", &b)) + if (http_GetHdr(hp, H_Content_Length, &b)) cls = pass_straight(sp, vc->fd, hp, b); - else if (http_HdrIs(hp, "Connection", "close")) + else if (http_HdrIs(hp, H_Connection, "close")) cls = pass_straight(sp, vc->fd, hp, NULL); - else if (http_HdrIs(hp, "Transfer-Encoding", "chunked")) + else if (http_HdrIs(hp, H_Transfer_Encoding, "chunked")) cls = pass_chunked(sp, vc->fd, hp); else { cls = pass_straight(sp, vc->fd, hp, NULL); } RES_Flush(sp); - if (http_GetHdr(hp, "Connection", &b) && !strcasecmp(b, "close")) + if (http_GetHdr(hp, H_Connection, &b) && !strcasecmp(b, "close")) cls = 1; if (cls) diff --git a/varnish-cache/bin/varnishd/cache_response.c b/varnish-cache/bin/varnishd/cache_response.c index 8596b62b..38bd09ac 100644 --- a/varnish-cache/bin/varnishd/cache_response.c +++ b/varnish-cache/bin/varnishd/cache_response.c @@ -126,7 +126,7 @@ res_do_304(struct sess *sp, char *p) RES_Write(sp, "Last-Modified: ", -1); RES_Write(sp, p, -1); RES_Write(sp, "\r\n", -1); - if (strcmp(sp->http->proto, "HTTP/1.1")) + if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START], "HTTP/1.1")) RES_Write(sp, "Connection: close\r\n", -1); sbuf_printf(sb, "X-Varnish: xid %u\r\n", sp->obj->xid); sbuf_printf(sb, "\r\n"); @@ -144,7 +144,7 @@ res_do_conds(struct sess *sp) time_t ims; if (sp->obj->last_modified > 0 && - http_GetHdr(sp->http, "If-Modified-Since", &p)) { + http_GetHdr(sp->http, H_If_Modified_Since, &p)) { ims = TIM_parse(p); if (ims > sp->t_req) /* [RFC2616 14.25] */ return (0); @@ -187,14 +187,14 @@ RES_WriteObj(struct sess *sp) sp->obj->age + sp->t_req - sp->obj->entered); sbuf_printf(sb, "Via: 1.1 varnish\r\n"); sbuf_printf(sb, "X-Varnish: xid %u\r\n", sp->obj->xid); - if (strcmp(sp->http->proto, "HTTP/1.1")) + if (strcmp(sp->http->hd[HTTP_HDR_PROTO][HTTP_START], "HTTP/1.1")) sbuf_printf(sb, "Connection: close\r\n"); sbuf_printf(sb, "\r\n"); sbuf_finish(sb); RES_Write(sp, sbuf_data(sb), sbuf_len(sb)); bytes += sbuf_len(sb); /* XXX: conditional request handling */ - if (!strcmp(sp->http->req, "GET")) { + if (!strcmp(sp->http->hd[HTTP_HDR_REQ][HTTP_START], "GET")) { TAILQ_FOREACH(st, &sp->obj->store, list) { assert(st->stevedore != NULL); u += st->len; diff --git a/varnish-cache/bin/varnishd/cache_session.c b/varnish-cache/bin/varnishd/cache_session.c index 0010a2b3..57ee780d 100644 --- a/varnish-cache/bin/varnishd/cache_session.c +++ b/varnish-cache/bin/varnishd/cache_session.c @@ -32,7 +32,6 @@ struct sessmem { struct sess sess; struct http http; - char *http_hdr; }; /*--------------------------------------------------------------------*/ @@ -170,10 +169,7 @@ SES_New(struct sockaddr *addr, unsigned len) (void)addr; /* XXX */ (void)len; /* XXX */ sm = calloc( - sizeof *sm + - heritage.mem_http_headers * sizeof sm->http_hdr + - heritage.mem_http_headerspace + - heritage.mem_workspace, + sizeof *sm + heritage.mem_workspace, 1); if (sm == NULL) return (NULL); @@ -182,7 +178,7 @@ SES_New(struct sockaddr *addr, unsigned len) sm->sess.magic = SESS_MAGIC; sm->sess.mem = sm; sm->sess.http = &sm->http; - http_Init(&sm->http, (void *)(sm + 1)); + http_Init(&sm->http, (void *)(sm + 1), heritage.mem_workspace); return (&sm->sess); } diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index a06d9295..9f711b65 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -56,11 +56,12 @@ VRT_GetHdr(struct sess *sp, const char *n) char * VRT_GetReq(struct sess *sp) { + char *p; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); assert(sp != NULL); assert(sp->http != NULL); - return (sp->http->req); + return (sp->http->hd[HTTP_HDR_REQ][HTTP_START]); } /*--------------------------------------------------------------------*/ diff --git a/varnish-cache/bin/varnishd/heritage.h b/varnish-cache/bin/varnishd/heritage.h index c51fdc37..405a7c47 100644 --- a/varnish-cache/bin/varnishd/heritage.h +++ b/varnish-cache/bin/varnishd/heritage.h @@ -42,8 +42,6 @@ struct heritage { unsigned wthread_timeout; /* Memory allocation hints */ - unsigned mem_http_headerspace; - unsigned mem_http_headers; unsigned mem_workspace; }; diff --git a/varnish-cache/bin/varnishd/rfc2616.c b/varnish-cache/bin/varnishd/rfc2616.c index 199b6ed6..eae184a1 100644 --- a/varnish-cache/bin/varnishd/rfc2616.c +++ b/varnish-cache/bin/varnishd/rfc2616.c @@ -83,10 +83,10 @@ RFC2616_Ttl(struct http *hp, time_t t_req, time_t t_resp, struct object *obj) retirement_age = INT_MAX; u1 = u2 = 0; - if (http_GetHdrField(hp, "Cache-Control", "max-age", &p)) { + if (http_GetHdrField(hp, H_Cache_Control, "max-age", &p)) { u1 = strtoul(p, NULL, 0); u2 = 0; - if (http_GetHdr(hp, "Age", &p)) { + if (http_GetHdr(hp, H_Age, &p)) { u2 = strtoul(p, NULL, 0); obj->age = u2; } @@ -95,11 +95,11 @@ RFC2616_Ttl(struct http *hp, time_t t_req, time_t t_resp, struct object *obj) } h_date = 0; - if (http_GetHdr(hp, "Date", &p)) + if (http_GetHdr(hp, H_Date, &p)) h_date = TIM_parse(p); h_expires = 0; - if (http_GetHdr(hp, "Expires", &p)) + if (http_GetHdr(hp, H_Expires, &p)) h_expires = TIM_parse(p); if (h_date < t_req && h_expires > t_req) { diff --git a/varnish-cache/bin/varnishd/varnishd.c b/varnish-cache/bin/varnishd/varnishd.c index f5c870ad..44bb1cdf 100644 --- a/varnish-cache/bin/varnishd/varnishd.c +++ b/varnish-cache/bin/varnishd/varnishd.c @@ -543,9 +543,7 @@ main(int argc, char *argv[]) heritage.wthread_min = 1; heritage.wthread_max = UINT_MAX; heritage.wthread_timeout = 10; - heritage.mem_http_headerspace= 4096; - heritage.mem_http_headers= 32; - heritage.mem_workspace = 0; + heritage.mem_workspace = 4096; while ((o = getopt(argc, argv, "b:df:h:p:s:t:w:")) != -1) switch (o) { diff --git a/varnish-cache/include/shmlog_tags.h b/varnish-cache/include/shmlog_tags.h index c3d8b828..38fc37f2 100644 --- a/varnish-cache/include/shmlog_tags.h +++ b/varnish-cache/include/shmlog_tags.h @@ -20,6 +20,7 @@ SLTM(BackendXID) SLTM(BackendReuse) SLTM(BackendClose) SLTM(HttpError) +SLTM(HttpGarbage) SLTM(ClientAddr) SLTM(Backend) SLTM(Request) diff --git a/varnish-cache/lib/libvcl/vcl_compile.c b/varnish-cache/lib/libvcl/vcl_compile.c index 54613611..012fc321 100644 --- a/varnish-cache/lib/libvcl/vcl_compile.c +++ b/varnish-cache/lib/libvcl/vcl_compile.c @@ -689,7 +689,8 @@ HeaderVar(struct tokenlist *tl __unused, struct token *t, struct var *vh) p[i] = '\0'; v->name = p; v->fmt = STRING; - asprintf(&p, "VRT_GetHdr(sp, \"%s\")", v->name + vh->len); + asprintf(&p, "VRT_GetHdr(sp, \"\\%03o%s:\")", + strlen(v->name + vh->len) + 1, v->name + vh->len); assert(p != NULL); v->rname = p; return (v);