Commit 0e31557a authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Make the VEC codes be 1, 2 and 8 byte wide length fields. It does not

make sense to add the overhead of a 4 byte code to save 0.0006% space.

Add standard entity expansion for URLs in <esi:include>

Now the new code passes all testcases :->

If you want to try it out, change
	#define OLD_ESI
to
	#undef OLD_ESI
at the top of bin/varnishd/cache.h

Once I have polished the new code a bit, it will become the default.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5740 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 62bc4a7d
......@@ -29,11 +29,11 @@
#define VEC_V1 'B'
#define VEC_V2 'W'
#define VEC_V4 'L'
#define VEC_V8 'L'
#define VEC_S1 'b'
#define VEC_S2 'w'
#define VEC_S4 'l'
#define VEC_S8 'l'
#define VEC_L1 'c'
#define VEC_L2 'x'
#define VEC_L4 'm'
#define VEC_L8 'm'
#define VEC_INCL 'I'
......@@ -121,9 +121,22 @@ ESI_Include(struct sess *sp, const char *src, const char *host)
#ifndef OLD_ESI
// #define Debug(fmt, ...) printf(fmt, __VA_ARGS__)
//#define Debug(fmt, ...) printf(fmt, __VA_ARGS__)
#define Debug(fmt, ...) /**/
static void
esi_sendchunk(struct sess *sp, const void *cb, ssize_t cl,
const void *ptr, ssize_t l)
{
Debug("VER(%d) %d\n", (int)l, (int)(cb-ce));
if (sp->wrk->res_mode & RES_CHUNKED)
WRW_Write(sp->wrk, cb, cl);
WRW_Write(sp->wrk, ptr, l);
if (sp->wrk->res_mode & RES_CHUNKED)
WRW_Write(sp->wrk, "\r\n", -1);
}
void
ESI_Deliver(struct sess *sp)
{
......@@ -150,26 +163,44 @@ ESI_Deliver(struct sess *sp)
p += 2;
q = (void*)strchr((const char*)p, '\0');
assert (q > p);
Debug("VER(%d) %d\n", (int)l, (int)(q-p));
if (sp->wrk->res_mode & RES_CHUNKED)
WRW_Write(sp->wrk, p, q - p);
WRW_Write(sp->wrk, st->ptr + off, l);
if (sp->wrk->res_mode & RES_CHUNKED)
WRW_Write(sp->wrk, "\r\n", -1);
// Debug("[%.*s]", (int)l, st->ptr + off);
esi_sendchunk(sp, p, q - p, st->ptr + off, l);
off += l;
p = q + 1;
break;
case VEC_V2:
l = vbe16dec(p + 1);
p += 3;
q = (void*)strchr((const char*)p, '\0');
assert (q > p);
esi_sendchunk(sp, p, q - p, st->ptr + off, l);
off += l;
p = q + 1;
break;
case VEC_V8:
l = vbe64dec(p + 1);
p += 9;
q = (void*)strchr((const char*)p, '\0');
assert (q > p);
esi_sendchunk(sp, p, q - p, st->ptr + off, l);
off += l;
p = q + 1;
break;
case VEC_S1:
l = p[1];
p += 2;
Debug("SKIP(%d)\n", (int)l);
Debug("SKIP1(%d)\n", (int)l);
off += l;
break;
case VEC_S2:
l = vbe16dec(p + 1);
p += 3;
Debug("SKIP(%d)\n", (int)l);
Debug("SKIP2(%d)\n", (int)l);
off += l;
break;
case VEC_S8:
l = vbe64dec(p + 1);
p += 9;
Debug("SKIP8(%d)\n", (int)l);
off += l;
break;
case VEC_L1:
......@@ -193,9 +224,9 @@ ESI_Deliver(struct sess *sp)
q++;
r = (void*)strchr((const char*)q, '\0');
AN(r);
Debug("INCL [%s][%s] BEGIN\n", p, q);
ESI_Include(sp, (const char*)p, (const char*)q);
Debug("INCL [%s] END\n", p);
Debug("INCL [%s][%s] BEGIN\n", q, p);
ESI_Include(sp, (const char*)q, (const char*)p);
Debug("INCL [%s][%s] END\n", q, p);
p = r + 1;
break;
default:
......
......@@ -43,7 +43,7 @@ SVNID("$Id")
#ifndef OLD_ESI
// #define Debug(fmt, ...) printf(fmt, __VA_ARGS__)
//#define Debug(fmt, ...) printf(fmt, __VA_ARGS__)
#define Debug(fmt, ...) /**/
struct vep_state;
......@@ -230,24 +230,26 @@ vep_match(struct vep_state *vep, const char *b, const char *e)
*/
static void
vep_emit_len(struct vep_state *vep, ssize_t l, int m8, int m16, int m32)
vep_emit_len(struct vep_state *vep, ssize_t l, int m8, int m16, int m64)
{
uint8_t buf[5];
uint8_t buf[9];
assert(l > 0);
if (l < 256) {
buf[0] = m8;
buf[1] = (uint8_t)l;
assert((ssize_t)buf[1] == l);
vsb_bcat(vep->vsb, buf, 2);
} else if (l < 65536) {
buf[0] = m16;
vbe16enc(buf + 1, (uint16_t)l);
assert((ssize_t)vbe16dec(buf + 1) == l);
vsb_bcat(vep->vsb, buf, 3);
} else {
/* XXX assert < 2^32 */
buf[0] = m32;
vbe32enc(buf + 1, (uint32_t)l);
vsb_bcat(vep->vsb, buf, 5);
buf[0] = m64;
vbe64enc(buf + 1, l);
assert((ssize_t)vbe64dec(buf + 1) == l);
vsb_bcat(vep->vsb, buf, 9);
}
}
......@@ -259,7 +261,7 @@ vep_emit_skip(struct vep_state *vep)
l = vep->o_skip;
vep->o_skip = 0;
assert(l > 0);
vep_emit_len(vep, l, VEC_S1, VEC_S2, VEC_S4);
vep_emit_len(vep, l, VEC_S1, VEC_S2, VEC_S8);
}
static void
......@@ -270,7 +272,7 @@ vep_emit_verbatim(struct vep_state *vep)
l = vep->o_verbatim;
vep->o_verbatim = 0;
assert(l > 0);
vep_emit_len(vep, l, VEC_V1, VEC_V2, VEC_V4);
vep_emit_len(vep, l, VEC_V1, VEC_V2, VEC_V8);
vsb_printf(vep->vsb, "%lx\r\n%c", l, 0);
}
......@@ -287,7 +289,7 @@ vep_emit_literal(struct vep_state *vep, const char *p, const char *e)
vep_emit_skip(vep);
l = e - p;
Debug("---->L(%d) [%.*s]\n", (int)l, (int)l, p);
vep_emit_len(vep, l, VEC_L1, VEC_L2, VEC_L4);
vep_emit_len(vep, l, VEC_L1, VEC_L2, VEC_L8);
vsb_printf(vep->vsb, "%lx\r\n%c", l, 0);
vsb_bcat(vep->vsb, p, l);
}
......@@ -427,18 +429,18 @@ vep_do_include(struct vep_state *vep, enum dowhat what)
l = vsb_len(vep->include_src);
h = 0;
vsb_printf(vep->vsb, "%c", VEC_INCL);
if (l > 7 && !memcmp(p, "http://", 7)) {
h = p + 7;
p = strchr(h, '/');
AN(p);
Debug("HOST <%.*s> PATH <%s>\n", (int)(p-h),h, p);
vsb_printf(vep->vsb, "%c%s%cHost: %.*s%c",
VEC_INCL, p, 0,
vsb_printf(vep->vsb, "Host: %.*s%c",
(int)(p-h), h, 0);
} else if (*p == '/') {
vsb_printf(vep->vsb, "%c%s%c%c",
VEC_INCL, p, 0, 0);
vsb_printf(vep->vsb, "%c", 0);
} else {
vsb_printf(vep->vsb, "%c", 0);
url = vep->sp->wrk->bereq->hd[HTTP_HDR_URL];
/* Look for the last / before a '?' */
h = NULL;
......@@ -448,13 +450,29 @@ vep_do_include(struct vep_state *vep, enum dowhat what)
if (h == NULL)
h = q + 1;
Debug("INCL:: %.*s/%s\n",
Debug("INCL:: [%.*s]/[%s]\n",
(int)(h - url.b), url.b, p);
vsb_printf(vep->vsb, "%c%.*s/%s%c%c",
VEC_INCL,
(int)(h - url.b), url.b,
p, 0, 0);
vsb_printf(vep->vsb, "%.*s/", (int)(h - url.b), url.b);
}
l -= (p - vsb_data(vep->include_src));
for (q = p; *q != '\0'; ) {
if (*q == '&') {
#define R(w,f,r) \
if (q + w <= p + l && !memcmp(q, f, w)) { \
vsb_printf(vep->vsb, "%c", r); \
q += l; \
continue; \
}
R(6, "&apos;", '\'');
R(6, "&quot;", '"');
R(4, "&lt;", '<');
R(4, "&gt;", '>');
R(5, "&amp;", '&');
}
vsb_printf(vep->vsb, "%c", *q++);
}
#undef R
vsb_printf(vep->vsb, "%c", 0);
vsb_delete(vep->include_src);
vep->include_src = NULL;
......
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