Commit 6d87f66b authored by Artur Bergman's avatar Artur Bergman

Merge r4049 r4066: Allows you to turn off ESI processing per request

Move the setting of the correct headers for ESI from ESI parsing time to delivery time. 
This is in anticipation for set req.esi = off; 

Allows you to turn off esi processing for a specific request using set req.esi = off even 
if the object has been esi processed -- this is useful if you have a cache heirarchy of 
varnish machines as well as debugging. 
Only change to processing is to store a copy of the attribute value instead of 
mangling to original. Committed from Oahu.



git-svn-id: http://www.varnish-cache.org/svn/branches/2.0@4082 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 1843ca98
......@@ -308,6 +308,7 @@ struct sess {
int restarts;
int esis;
int disable_esi;
struct worker *wrk;
......
......@@ -824,6 +824,8 @@ cnt_recv(struct sess *sp)
sp->director = sp->vcl->director[0];
AN(sp->director);
sp->disable_esi = 0;
VCL_recv_method(sp);
if (sp->restarts >= params->max_restarts) {
if (sp->err_code == 0)
......
......@@ -106,9 +106,12 @@ RES_BuildHttp(struct sess *sp)
HTTPH_A_DELIVER);
/* Only HTTP 1.1 can do Chunked encoding */
if (sp->http->protover < 1.1 && !VTAILQ_EMPTY(&sp->obj->esibits))
http_Unset(sp->http, H_Transfer_Encoding);
if (!sp->disable_esi && !VTAILQ_EMPTY(&sp->obj->esibits)) {
http_Unset(sp->http, H_Content_Length);
if(sp->http->protover >= 1.1)
http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Transfer-Encoding: chunked");
}
TIM_format(TIM_real(), time_str);
http_PrintfHeader(sp->wrk, sp->fd, sp->http, "Date: %s", time_str);
......@@ -139,10 +142,10 @@ RES_WriteObj(struct sess *sp)
WRW_Reserve(sp->wrk, &sp->fd);
if (sp->esis == 0)
if (sp->disable_esi || sp->esis == 0)
sp->acct_req.hdrbytes += http_Write(sp->wrk, sp->http, 1);
if (sp->wantbody && !VTAILQ_EMPTY(&sp->obj->esibits)) {
if (!sp->disable_esi && sp->wantbody && !VTAILQ_EMPTY(&sp->obj->esibits)) {
if (WRW_FlushRelease(sp->wrk)) {
vca_close_session(sp, "remote closed");
return;
......@@ -152,7 +155,8 @@ RES_WriteObj(struct sess *sp)
}
if (sp->wantbody) {
if (sp->esis > 0 &&
if (!sp->disable_esi &&
sp->esis > 0 &&
sp->http->protover >= 1.1 &&
sp->obj->len > 0) {
sprintf(lenbuf, "%x\r\n", sp->obj->len);
......@@ -183,7 +187,8 @@ RES_WriteObj(struct sess *sp)
(void)WRW_Write(sp->wrk, st->ptr, st->len);
}
assert(u == sp->obj->len);
if (sp->esis > 0 &&
if (!sp->disable_esi &&
sp->esis > 0 &&
sp->http->protover >= 1.1 &&
sp->obj->len > 0)
(void)WRW_Write(sp->wrk, "\r\n", -1);
......
......@@ -306,7 +306,8 @@ SES_New(const struct sockaddr *addr, unsigned len)
sp->t_resp = NAN;
sp->t_end = NAN;
sp->grace = NAN;
sp->disable_esi = 0;
assert(len <= sp->sockaddrlen);
if (addr != NULL) {
memcpy(sp->sockaddr, addr, len);
......
......@@ -496,6 +496,22 @@ VRT_r_req_backend(struct sess *sp)
/*--------------------------------------------------------------------*/
void
VRT_l_req_esi(struct sess *sp, unsigned process_esi)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
sp->disable_esi = !process_esi;
}
unsigned
VRT_r_req_esi(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return (!sp->disable_esi);
}
/*--------------------------------------------------------------------*/
int
VRT_r_req_restarts(const struct sess *sp)
{
......
......@@ -304,8 +304,7 @@ esi_attrib(const struct esi_work *ew, txt *in, txt *attrib, txt *val)
in->b++;
if (isspace(*in->b)) {
val->e = val->b = in->b;;
*val->e = '\0';
val->e = val->b = in->b;
in->b++;
return (1);
}
......@@ -340,7 +339,6 @@ esi_attrib(const struct esi_work *ew, txt *in, txt *attrib, txt *val)
val->e = in->b;
in->b++;
}
*val->e = '\0';
return (1);
}
......@@ -352,11 +350,11 @@ static void
esi_handle_include(struct esi_work *ew)
{
struct esi_bit *eb;
char *p, *q;
char *p, *q, *c;
txt t = ew->tag;
txt tag;
txt val;
unsigned u, v;
unsigned u, v, s;
struct ws *ws;
if (ew->eb == NULL || ew->eb->include.b != NULL)
......@@ -375,6 +373,20 @@ esi_handle_include(struct esi_work *ew)
continue;
}
/* Wee are saving the original string */
ws = ew->sp->obj->ws_o;
WS_Assert(ws);
s = 0;
if ( val.b != val.e ) {
s = Tlen(val) + 1;
c = WS_Alloc(ws, s);
memcpy(c, val.b, Tlen(val));
val.b = c;
val.e = val.b + s;
*val.e = '\0';
}
if (Tlen(val) > 7 && !memcmp(val.b, "http://", 7)) {
/* Rewrite to Host: header inplace */
eb->host.b = val.b;
......@@ -406,8 +418,6 @@ esi_handle_include(struct esi_work *ew)
/* Use the objects WS to store the result */
CHECK_OBJ_NOTNULL(ew->sp->obj, OBJECT_MAGIC);
ws = ew->sp->obj->ws_o;
WS_Assert(ws);
/* Look for the last '/' before a '?' */
q = NULL;
......@@ -747,13 +757,6 @@ VRT_ESI(struct sess *sp)
if (ew->incmt)
esi_error(ew, ew->t.e, -1,
"ESI 1.0 unterminated <!--esi comment");
/*
* Our ESI implementation needs chunked encoding
*/
http_Unset(sp->obj->http, H_Content_Length);
http_PrintfHeader(sp->wrk, sp->fd, sp->obj->http,
"Transfer-Encoding: chunked");
}
/*--------------------------------------------------------------------*/
......
# $Id$
test "ESI requests turned off"
server s1 {
rxreq
txresp -body {
<html>
Before include
<esi:include src="/body"/>
After include
}
rxreq
txresp -body {
<html>
Before include
<esi:include src="/body"/>
After include
}
rxreq
expect req.url == "/body"
txresp -body {
Included file
}
} -start
varnish v1 -vcl+backend {
sub vcl_fetch {
if(req.url == "/") {
set req.esi = false;
}
esi;
}
} -start
client c1 {
txreq
rxresp
expect resp.bodylen == 73
expect resp.status == 200
txreq -url "/esi"
rxresp
expect resp.bodylen == 65
expect resp.status == 200
}
client c1 -run
varnish v1 -expect esi_errors == 0
......@@ -24,6 +24,8 @@ int VRT_r_req_restarts(const struct sess *);
double VRT_r_req_grace(struct sess *);
void VRT_l_req_grace(struct sess *, double);
const char * VRT_r_req_xid(struct sess *);
unsigned VRT_r_req_esi(struct sess *);
void VRT_l_req_esi(struct sess *, unsigned);
const char * VRT_r_bereq_request(const struct sess *);
void VRT_l_bereq_request(const struct sess *, const char *, ...);
const char * VRT_r_bereq_url(const struct sess *);
......
......@@ -324,9 +324,9 @@ vcl_output_lang_h(struct vsb *sb)
/* ../../include/vrt_obj.h */
vsb_cat(sb, "/*\n * $Id: vrt_obj.h 3990 2009-03-23 12:37:42Z tfheen");
vsb_cat(sb, " $\n *\n * NB: This file is machine generated, DO NOT");
vsb_cat(sb, " EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n");
vsb_cat(sb, "/*\n * $Id: vcc_gen_obj.tcl 3992 2009-03-23 12:50:04Z ");
vsb_cat(sb, "tfheen $\n *\n * NB: This file is machine generated, ");
vsb_cat(sb, "DO NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n");
vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct ");
vsb_cat(sb, "sess *);\nstruct sockaddr * VRT_r_server_ip(struct ses");
vsb_cat(sb, "s *);\nconst char * VRT_r_server_hostname(struct sess ");
......@@ -345,6 +345,8 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "uct sess *);\ndouble VRT_r_req_grace(struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_grace(struct sess *, double);\n");
vsb_cat(sb, "const char * VRT_r_req_xid(struct sess *);\n");
vsb_cat(sb, "unsigned VRT_r_req_esi(struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_esi(struct sess *, unsigned);\n");
vsb_cat(sb, "const char * VRT_r_bereq_request(const struct sess *);");
vsb_cat(sb, "\nvoid VRT_l_bereq_request(const struct sess *, const ");
vsb_cat(sb, "char *, ...);\nconst char * VRT_r_bereq_url(const stru");
......
......@@ -116,6 +116,12 @@ set spobj {
"struct sess *"
}
{ req.esi
RW BOOL
{recv fetch deliver error}
"struct sess *"
}
# Request sent to backend
{ bereq.request
RW STRING
......
......@@ -102,6 +102,11 @@ struct var vcc_vars[] = {
| VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
| VCL_MET_ERROR
},
{ "req.esi", BOOL, 7,
"VRT_r_req_esi(sp)", "VRT_l_req_esi(sp, ",
V_RW, 0,
VCL_MET_RECV | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_ERROR
},
{ "bereq.request", STRING, 13,
"VRT_r_bereq_request(sp)", "VRT_l_bereq_request(sp, ",
V_RW, 0,
......
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