]> err.no Git - varnish/commitdiff
Yet another refinement to the way we store and deal with HTTP headers.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 20 Jul 2006 22:08:43 +0000 (22:08 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 20 Jul 2006 22:08:43 +0000 (22:08 +0000)
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

16 files changed:
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_hash.c
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cache_pass.c
varnish-cache/bin/varnishd/cache_response.c
varnish-cache/bin/varnishd/cache_session.c
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/bin/varnishd/heritage.h
varnish-cache/bin/varnishd/rfc2616.c
varnish-cache/bin/varnishd/varnishd.c
varnish-cache/include/shmlog_tags.h
varnish-cache/lib/libvcl/vcl_compile.c

index f3b1407158e5773ab6d3bfae87b7acf0b4ae28a0..1742927f2123ab132c9309e746fd18c2023f69ac 100644 (file)
 
 #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);
index fd80dd906a2abc723895624f693bd44dbdc2acf2..a00881e87b7814089a53178d7f09c1aefd7ea5fb 100644 (file)
@@ -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);
 }
 
index e7384838069dcee7ded7d28e691935c9a1c85238..374801ad5514365475c5b3c619c8dd5c6165f4a3 100644 (file)
@@ -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);
index 6cf3f04ef505bf78c0dcb197916ed494e74b25dc..1d30c53a692e26915590682a79c5005715472198 100644 (file)
@@ -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)
index 77f91ae36154675215e0e51368834ab7f74822d0..fb11aa7edc16a56f9df413e10935a6ae37374e3c 100644 (file)
@@ -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);
index 889f34c87791b5d0de7c7a0e75ca1731a1ca8f0e..dd660afe2f8af7d1397dc8d4f6a838085d910d82 100644 (file)
 #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
+}
index 8badc7ab2e32c0b8bde4c5d38fce5e235f803f0e..f95f2aaefbcfd6f37a83993b74da9e116ff07956 100644 (file)
@@ -105,6 +105,7 @@ child_main(void)
        VCL_Init();
        VCL_Load(heritage.vcl_file, "boot", NULL);
 
+       HTTP_Init();
        SES_Init();
 
        VBE_Init();
index 23530fd2cf627fe1774b447badca7e20e64488c3..14c33e9b2a8b284158c5a4b47f660fdb7d1fcb06 100644 (file)
@@ -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)
index 8596b62b703a1b4b08f8d6a816334e08b6953bd9..38bd09ac1f4450b29c69061157de11a0e32f6d7d 100644 (file)
@@ -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;
index 0010a2b318910ffe4673403ef8cb3f673dfa7c20..57ee780d289625490059774eb75e34b7c0c8b6b4 100644 (file)
@@ -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);
 }
 
index a06d92958f060f6f7ff7c6a5a2d7d7ba71ee9f95..9f711b654482d8cc09e2adf059879b680f4fb3c6 100644 (file)
@@ -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]);
 }
 
 /*--------------------------------------------------------------------*/
index c51fdc373ac73576aa310b1995b0f3763eadae09..405a7c476e784c885c477a57828e882f9c96e514 100644 (file)
@@ -42,8 +42,6 @@ struct heritage {
        unsigned                wthread_timeout;
 
        /* Memory allocation hints */
-       unsigned                mem_http_headerspace;
-       unsigned                mem_http_headers;
        unsigned                mem_workspace;
 };
 
index 199b6ed631cb6c3a7ab3a6b67bcedc48389090c5..eae184a1b2c0e4da40544f016aee587f06b05c85 100644 (file)
@@ -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) {
index f5c870adad3aa110829d039b8e4ca0545050b326..44bb1cdfc2085c168e078d627b06574d837915ca 100644 (file)
@@ -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) {
index c3d8b828cc7fa05d161535958f56a0489bd4d2ed..38fc37f2b1f7bce039950af5d9125d204b441943 100644 (file)
@@ -20,6 +20,7 @@ SLTM(BackendXID)
 SLTM(BackendReuse)
 SLTM(BackendClose)
 SLTM(HttpError)
+SLTM(HttpGarbage)
 SLTM(ClientAddr)
 SLTM(Backend)
 SLTM(Request)
index 546136114719a923eaf067520ea42e3de592dd57..012fc3219902b9bce5b3e60c4e869c1106cc042c 100644 (file)
@@ -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);