From 27b0ad735ba36dc9fd9a95c6b0838c2366fb9d22 Mon Sep 17 00:00:00 2001 From: phk Date: Thu, 5 Jul 2007 09:47:52 +0000 Subject: [PATCH] Implement setting of HTTP headers: 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 | 1 + varnish-cache/bin/varnishd/cache_http.c | 10 ++++++-- varnish-cache/bin/varnishd/cache_vrt.c | 29 +++++++++++++++++++++++- varnish-cache/lib/libvcl/vcc_action.c | 15 ++++++++---- varnish-cache/lib/libvcl/vcc_compile.h | 1 + varnish-cache/lib/libvcl/vcc_gen_obj.tcl | 1 + varnish-cache/lib/libvcl/vcc_obj.c | 28 +++++++++++++++++++++++ varnish-cache/lib/libvcl/vcc_var.c | 3 ++- 8 files changed, 79 insertions(+), 9 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 9ba90593..1a8c9d33 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -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[]; diff --git a/varnish-cache/bin/varnishd/cache_http.c b/varnish-cache/bin/varnishd/cache_http.c index 65ddf873..e3ff9f40 100644 --- a/varnish-cache/bin/varnishd/cache_http.c +++ b/varnish-cache/bin/varnishd/cache_http.c @@ -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]); } /*--------------------------------------------------------------------*/ diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index 7cdef770..5a29dba2 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -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); } diff --git a/varnish-cache/lib/libvcl/vcc_action.c b/varnish-cache/lib/libvcl/vcc_action.c index 32ad8f22..57efb55b 100644 --- a/varnish-cache/lib/libvcl/vcc_action.c +++ b/varnish-cache/lib/libvcl/vcc_action.c @@ -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, "%s, 0);\n", vp->lname); + Fb(tl, 1, "%s0);\n", vp->lname); vcc_NextToken(tl); - ExpectErr(tl, ';'); } /*--------------------------------------------------------------------*/ diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index 45e45eb6..f51fd706 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -121,6 +121,7 @@ struct var { const char *rname; const char *lname; enum {V_RO, V_RW, V_WO} access; + char ishdr; unsigned methods; }; diff --git a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl index 10f6c603..6ccfe082 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl @@ -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\}," diff --git a/varnish-cache/lib/libvcl/vcc_obj.c b/varnish-cache/lib/libvcl/vcc_obj.c index 1d6d710e..bb11ecf5 100644 --- a/varnish-cache/lib/libvcl/vcc_obj.c +++ b/varnish-cache/lib/libvcl/vcc_obj.c @@ -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 } diff --git a/varnish-cache/lib/libvcl/vcc_var.c b/varnish-cache/lib/libvcl/vcc_var.c index 15b062f5..c191af11 100644 --- a/varnish-cache/lib/libvcl/vcc_var.c +++ b/varnish-cache/lib/libvcl/vcc_var.c @@ -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; -- 2.39.5