]> err.no Git - varnish/commitdiff
Implement setting of HTTP headers:
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 5 Jul 2007 09:47:52 +0000 (09:47 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 5 Jul 2007 09:47:52 +0000 (09:47 +0000)
sub vcl_deliver {
set resp.http.phk = "Beastie" "Rules";
}

Would result in a new header line:

phk: BeastieRules

Notice that strings are concatenated directly, you add spaces, commas etc
where you want them.

Other variables which have STRING format (or which can be converted to
STRING format) can also be used:

sub vcl_deliver {
set resp.http.phk = "Server is: " resp.http.server ;
}

Could result in:

phk: Server is: Apache/1.3.x LaHonda (Unix)

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1646 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_http.c
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/lib/libvcl/vcc_action.c
varnish-cache/lib/libvcl/vcc_compile.h
varnish-cache/lib/libvcl/vcc_gen_obj.tcl
varnish-cache/lib/libvcl/vcc_obj.c
varnish-cache/lib/libvcl/vcc_var.c

index 9ba90593471100cdb290f0817995e4c18521d460..1a8c9d3305b37920fc148fad1f8a05f77924d54b 100644 (file)
@@ -428,6 +428,7 @@ int http_DissectResponse(struct worker *w, struct http *sp, int fd);
 void http_DoConnection(struct sess *sp);
 void http_CopyHome(struct worker *w, int fd, struct http *hp);
 void http_Unset(struct http *hp, const char *hdr);
+void http_LogLostHeader(struct worker *w, int fd, struct http *hp, const char *hdr);
 
 
 #define HTTPH(a, b, c, d, e, f, g) extern char b[];
index 65ddf87383bcf796eee574202b2a06f7c035a49c..e3ff9f407b5e1af21813c1138c246bd17e1ac0c8 100644 (file)
@@ -91,10 +91,16 @@ http2shmlog(struct http *hp, enum httptag t)
 }
 
 static void
-WSLH(struct worker *w, enum httptag t, unsigned xid, struct http *hp, int hdr)
+WSLH(struct worker *w, enum httptag t, unsigned fd, struct http *hp, int hdr)
 {
 
-       WSLR(w, http2shmlog(hp, t), xid, hp->hd[hdr].b, hp->hd[hdr].e);
+       WSLR(w, http2shmlog(hp, t), fd, hp->hd[hdr].b, hp->hd[hdr].e);
+}
+
+void
+http_LogLostHeader(struct worker *w, int fd, struct http *hp, const char *hdr)
+{
+       WSLR(w, http2shmlog(hp, HTTP_T_LostHeader), fd, hdr + 1, hdr + hdr[0]);
 }
 
 /*--------------------------------------------------------------------*/
index 7cdef770654b241c1e6a9f4cd7d0cd023b80f3cb..5a29dba248476b241340e30f12c8b1de8007577a 100644 (file)
@@ -118,6 +118,8 @@ VRT_SetHdr(struct sess *sp , enum gethdr_e where, const char *hdr, ...)
        struct http *hp;
        va_list ap;
        const char *p;
+       char *b, *e;
+       unsigned u, x;
 
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
        hp = vrt_selecthttp(sp, where);
@@ -126,7 +128,32 @@ VRT_SetHdr(struct sess *sp , enum gethdr_e where, const char *hdr, ...)
        if (p == NULL) {
                http_Unset(hp, hdr);
        } else {
-               INCOMPL();
+               u = WS_Reserve(hp->ws, 0);
+               e = b = hp->ws->f;
+               *e = '\0';
+               x = strlen(hdr + 1);
+               if (x + 1 < u)
+                       memcpy(e, hdr + 1, x);
+               e += x;
+               if (1 + 1 < u)
+                       *e++ = ' ';
+               while (p != NULL) {
+                       x = strlen(p);
+                       if (x + 1 < u)
+                               memcpy(e, p, x);
+                       e += x;
+                       p = va_arg(ap, const char *);
+               }
+               *e = '\0';
+               if (e > b + u) {
+                       http_LogLostHeader(sp->wrk, sp->fd, hp, hdr);
+                       WS_Release(hp->ws, 0);
+                       
+               } else {
+                       WS_Release(hp->ws, 1 + e - b);
+                       http_Unset(hp, hdr);
+                       http_SetHeader(sp->wrk, sp->fd, hp, b);
+               }
        }
        va_end(ap);
 }
index 32ad8f2218d213cedb9a7bc00a38b657e4c69f52..57efb55b27a48f758f3d6a4955301ca82278c52f 100644 (file)
@@ -209,6 +209,13 @@ parse_set(struct tokenlist *tl)
                }
                vcc_NextToken(tl);
                vcc_StringVal(tl);
+               if (vp->ishdr) {
+                       while (tl->t->tok != ';') {
+                               Fb(tl, 0, ", ");
+                               vcc_StringVal(tl);
+                       }
+                       Fb(tl, 0, ", 0");
+               }
                Fb(tl, 0, ");\n");
                break;
        default:
@@ -231,17 +238,15 @@ parse_remove(struct tokenlist *tl)
        ExpectErr(tl, VAR);
        vt = tl->t;
        vp = vcc_FindVar(tl, tl->t, vcc_vars);
-       if (vp->fmt != STRING) {
-               vsb_printf(tl->sb,
-                   "Only STRING variables can be removed.\n");
+       if (vp->fmt != STRING || !vp->ishdr) {
+               vsb_printf(tl->sb, "Only http header lines can be removed.\n");
                vcc_ErrWhere(tl, tl->t);
                return;
        }
        check_writebit(tl, vp);
        ERRCHK(tl);
-       Fb(tl, 1, "%s0);\n", vp->lname);
+       Fb(tl, 1, "%s0);\n", vp->lname);
        vcc_NextToken(tl);
-       ExpectErr(tl, ';');
 }
 
 /*--------------------------------------------------------------------*/
index 45e45eb62dd58c227ac4559d87b7be77e34b52fb..f51fd706cac535353b2c3ffde7f8607b2fc3e0ea 100644 (file)
@@ -121,6 +121,7 @@ struct var {
        const char              *rname;
        const char              *lname;
        enum {V_RO, V_RW, V_WO} access;
+       char                    ishdr;
        unsigned                methods;
 };
 
index 10f6c6038f1e8f01b44fcc3aa33b5409052b9634..6ccfe0825b349fd48f5fa0bc03ddcf957be0ecc2 100755 (executable)
@@ -231,6 +231,7 @@ proc vars {v ty pa} {
                        puts $fo  "\t    NULL,"
                }
                puts $fo  "\t    V_$a,"
+               puts $fo  "\t    0,"
                puts $fo  "\t    [method_map [lindex $v 3]]"
                puts $fo "\t\},"
 
index 1d6d710e1353b0bc7d15051283328fd71c61c486..bb11ecf530891351afdf42ebde62b9435820cb70 100644 (file)
@@ -14,18 +14,21 @@ struct var vcc_be_vars[] = {
            NULL,
            "VRT_l_backend_host(backend, ",
            V_WO,
+           0,
            
        },
        { "backend.port", PORTNAME, 12,
            NULL,
            "VRT_l_backend_port(backend, ",
            V_WO,
+           0,
            
        },
        { "backend.dnsttl", TIME, 14,
            NULL,
            "VRT_l_backend_dnsttl(backend, ",
            V_WO,
+           0,
            
        },
        { NULL }
@@ -36,150 +39,175 @@ struct var vcc_vars[] = {
            "VRT_r_client_ip(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
        },
        { "server.ip", IP, 9,
            "VRT_r_server_ip(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
        },
        { "req.request", STRING, 11,
            "VRT_r_req_request(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
        },
        { "req.url", STRING, 7,
            "VRT_r_req_url(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
        },
        { "req.proto", STRING, 9,
            "VRT_r_req_proto(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
        },
        { "req.http.", HEADER, 9,
            "VRT_r_req_http_(sp)",
            "VRT_l_req_http_(sp, ",
            V_RW,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
        },
        { "req.hash", HASH, 8,
            NULL,
            "VRT_l_req_hash(sp, ",
            V_WO,
+           0,
            VCL_MET_HASH
        },
        { "req.backend", BACKEND, 11,
            "VRT_r_req_backend(sp)",
            "VRT_l_req_backend(sp, ",
            V_RW,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH
        },
        { "bereq.request", STRING, 13,
            "VRT_r_bereq_request(sp)",
            "VRT_l_bereq_request(sp, ",
            V_RW,
+           0,
            VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_MISS
        },
        { "bereq.url", STRING, 9,
            "VRT_r_bereq_url(sp)",
            "VRT_l_bereq_url(sp, ",
            V_RW,
+           0,
            VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_MISS
        },
        { "bereq.proto", STRING, 11,
            "VRT_r_bereq_proto(sp)",
            "VRT_l_bereq_proto(sp, ",
            V_RW,
+           0,
            VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_MISS
        },
        { "bereq.http.", HEADER, 11,
            "VRT_r_bereq_http_(sp)",
            "VRT_l_bereq_http_(sp, ",
            V_RW,
+           0,
            VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_MISS
        },
        { "obj.proto", STRING, 9,
            "VRT_r_obj_proto(sp)",
            "VRT_l_obj_proto(sp, ",
            V_RW,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH
        },
        { "obj.status", INT, 10,
            "VRT_r_obj_status(sp)",
            "VRT_l_obj_status(sp, ",
            V_RW,
+           0,
            VCL_MET_FETCH
        },
        { "obj.response", STRING, 12,
            "VRT_r_obj_response(sp)",
            "VRT_l_obj_response(sp, ",
            V_RW,
+           0,
            VCL_MET_FETCH
        },
        { "obj.http.", HEADER, 9,
            "VRT_r_obj_http_(sp)",
            "VRT_l_obj_http_(sp, ",
            V_RW,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH
        },
        { "obj.valid", BOOL, 9,
            "VRT_r_obj_valid(sp)",
            "VRT_l_obj_valid(sp, ",
            V_RW,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT
        },
        { "obj.cacheable", BOOL, 13,
            "VRT_r_obj_cacheable(sp)",
            "VRT_l_obj_cacheable(sp, ",
            V_RW,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT
        },
        { "obj.ttl", TIME, 7,
            "VRT_r_obj_ttl(sp)",
            "VRT_l_obj_ttl(sp, ",
            V_RW,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DISCARD | VCL_MET_TIMEOUT
        },
        { "obj.lastuse", TIME, 11,
            "VRT_r_obj_lastuse(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT
        },
        { "resp.proto", STRING, 10,
            "VRT_r_resp_proto(sp)",
            "VRT_l_resp_proto(sp, ",
            V_RW,
+           0,
            VCL_MET_DELIVER
        },
        { "resp.status", INT, 11,
            "VRT_r_resp_status(sp)",
            "VRT_l_resp_status(sp, ",
            V_RW,
+           0,
            VCL_MET_DELIVER
        },
        { "resp.response", STRING, 13,
            "VRT_r_resp_response(sp)",
            "VRT_l_resp_response(sp, ",
            V_RW,
+           0,
            VCL_MET_DELIVER
        },
        { "resp.http.", HEADER, 10,
            "VRT_r_resp_http_(sp)",
            "VRT_l_resp_http_(sp, ",
            V_RW,
+           0,
            VCL_MET_DELIVER
        },
        { "now", TIME, 3,
            "VRT_r_now(sp)",
            NULL,
            V_RO,
+           0,
            VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT
        },
        { NULL }
index 15b062f5931ca7ed084de53052400779d84f6e92..c191af1119b1c37c2a187daaccfd6a70aed11176 100644 (file)
@@ -93,6 +93,7 @@ HeaderVar(struct tokenlist *tl, const struct token *t, const struct var *vh)
        v->name = p;
        v->access = V_RW;
        v->fmt = STRING;
+       v->ishdr = 1;
        v->methods = vh->methods;
        if (!memcmp(vh->name, "req.", 4))
                wh = "HDR_REQ";
@@ -108,7 +109,7 @@ HeaderVar(struct tokenlist *tl, const struct token *t, const struct var *vh)
            (unsigned)(strlen(v->name + vh->len) + 1), v->name + vh->len);
        AN(p);
        v->rname = p;
-       asprintf(&p, "VRT_SetHdr(sp, %s, \"\\%03o%s:\"", wh,
+       asprintf(&p, "VRT_SetHdr(sp, %s, \"\\%03o%s:\"", wh,
            (unsigned)(strlen(v->name + vh->len) + 1), v->name + vh->len);
        AN(p);
        v->lname = p;