Commit 753bc5a6 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@1646 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent e7cad46b
......@@ -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[];
......
......@@ -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]);
}
/*--------------------------------------------------------------------*/
......
......@@ -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);
}
......
......@@ -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, ';');
}
/*--------------------------------------------------------------------*/
......
......@@ -121,6 +121,7 @@ struct var {
const char *rname;
const char *lname;
enum {V_RO, V_RW, V_WO} access;
char ishdr;
unsigned methods;
};
......
......@@ -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\},"
......
......@@ -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 }
......
......@@ -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;
......
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