[master] 4b9ac08 Add a "hole-through" path that does the trivial bit of streaming.
Poul-Henning Kamp
phk at varnish-cache.org
Mon Apr 11 12:50:18 CEST 2011
commit 4b9ac086b43104be28ee09abf882592d20f2fb87
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Apr 11 10:49:41 2011 +0000
Add a "hole-through" path that does the trivial bit of streaming.
Now for all the hard bits...
diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index d280bb1..a1ea70c 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -312,6 +312,9 @@ struct worker {
unsigned do_close;
char *h_content_length;
+ /* Stream state */
+ ssize_t stream_next;
+
/* ESI stuff */
struct vep_state *vep;
int gzip_resp;
@@ -858,6 +861,7 @@ void RES_BuildHttp(struct sess *sp);
void RES_WriteObj(struct sess *sp);
void RES_StreamStart(struct sess *sp);
void RES_StreamEnd(struct sess *sp);
+void RES_StreamPoll(const struct sess *sp);
/* cache_vary.c */
struct vsb *VRY_Create(const struct sess *sp, const struct http *hp);
diff --git a/bin/varnishd/cache_fetch.c b/bin/varnishd/cache_fetch.c
index 78c7af8..87ce092 100644
--- a/bin/varnishd/cache_fetch.c
+++ b/bin/varnishd/cache_fetch.c
@@ -102,6 +102,8 @@ vfp_nop_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
st->len += w;
sp->obj->len += w;
bytes -= w;
+ if (sp->wrk->do_stream)
+ RES_StreamPoll(sp);
}
return (1);
}
diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c
index 7e389c9..a07eeeb 100644
--- a/bin/varnishd/cache_gzip.c
+++ b/bin/varnishd/cache_gzip.c
@@ -477,6 +477,8 @@ vfp_gunzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
i = VGZ_Gunzip(vg, &dp, &dl);
assert(i == VGZ_OK || i == VGZ_END);
sp->obj->len += dl;
+ if (sp->wrk->do_stream)
+ RES_StreamPoll(sp);
}
if (i == Z_OK || i == Z_STREAM_END)
return (1);
@@ -547,6 +549,8 @@ vfp_gzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
i = VGZ_Gzip(vg, &dp, &dl, VGZ_NORMAL);
assert(i == Z_OK);
sp->obj->len += dl;
+ if (sp->wrk->do_stream)
+ RES_StreamPoll(sp);
}
return (1);
}
@@ -623,6 +627,8 @@ vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
VGZ_Ibuf(vg, st->ptr + st->len, w);
st->len += w;
sp->obj->len += w;
+ if (sp->wrk->do_stream)
+ RES_StreamPoll(sp);
while (!VGZ_IbufEmpty(vg)) {
VGZ_Obuf(vg, ibuf, sizeof ibuf);
diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c
index 4771c54..2fbf120 100644
--- a/bin/varnishd/cache_response.c
+++ b/bin/varnishd/cache_response.c
@@ -270,7 +270,7 @@ res_WriteGunzipObj(struct sess *sp)
}
if (obufl) {
(void)WRW_Write(sp->wrk, obuf, obufl);
- WRW_Flush(sp->wrk);
+ (void)WRW_Flush(sp->wrk);
}
VGZ_Destroy(&vg);
assert(u == sp->obj->len);
@@ -413,19 +413,42 @@ RES_StreamStart(struct sess *sp)
if (sp->wrk->res_mode & RES_CHUNKED)
WRW_Chunked(sp->wrk);
+
+ sp->wrk->stream_next = 0;
+}
+
+void
+RES_StreamPoll(const struct sess *sp)
+{
+ struct storage *st;
+ ssize_t l, l2;
+ void *ptr;
+
+ if (sp->obj->len == sp->wrk->stream_next)
+ return;
+ assert(sp->obj->len > sp->wrk->stream_next);
+ l = 0;
+ VTAILQ_FOREACH(st, &sp->obj->store, list) {
+ if (st->len + l <= sp->wrk->stream_next) {
+ l += st->len;
+ continue;
+ }
+ l2 = st->len + l - sp->wrk->stream_next;
+ ptr = st->ptr + (sp->wrk->stream_next - l);
+ (void)WRW_Write(sp->wrk, ptr, l2);
+ l += st->len;
+ sp->wrk->stream_next += l2;
+ }
+ (void)WRW_Flush(sp->wrk);
}
void
RES_StreamEnd(struct sess *sp)
{
- ssize_t low, high;
if (sp->wrk->res_mode & RES_GUNZIP) {
+ INCOMPL();
res_WriteGunzipObj(sp);
- } else {
- low = 0;
- high = sp->obj->len - 1;
- res_WriteDirObj(sp, low, high);
}
if (sp->wrk->res_mode & RES_CHUNKED &&
!(sp->wrk->res_mode & RES_ESI_CHILD))
diff --git a/bin/varnishtest/tests/README b/bin/varnishtest/tests/README
index 8b2ec15..48924a2 100644
--- a/bin/varnishtest/tests/README
+++ b/bin/varnishtest/tests/README
@@ -15,10 +15,14 @@ Naming scheme
[id]%05d.vtc
- id ~ [a] --> varnishtester(1) tests
+ id ~ [a] --> varnishtest(1) tests
id ~ [b] --> Basic functionality tests
id ~ [c] --> Complex functionality tests
id ~ [e] --> ESI tests
+ id ~ [g] --> GZIP tests
+ id ~ [m] --> VMOD tests
+ id ~ [p] --> Persistent tests
id ~ [r] --> Regression tests, same number as ticket
id ~ [s] --> Slow tests, expiry, grace etc.
+ id ~ [t] --> sTreaming tests
id ~ [v] --> VCL tests: execute VRT functions
diff --git a/bin/varnishtest/tests/t00000.vtc b/bin/varnishtest/tests/t00000.vtc
new file mode 100644
index 0000000..7116b42
--- /dev/null
+++ b/bin/varnishtest/tests/t00000.vtc
@@ -0,0 +1,50 @@
+# $Id$
+
+test "Ticket #873"
+
+server s1 {
+ rxreq
+ txresp -nolen -hdr "Transfer-encoding: chunked"
+ chunked "<1>------------------------<1>\n"
+ sema r1 sync 2
+ chunked "<2>------------------------<2>\n"
+ sema r2 sync 2
+ chunked "<3>------------------------<3>\n"
+ sema r1 sync 2
+ chunked "<4>------------------------<4>\n"
+ sema r2 sync 2
+ chunkedlen 0
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.do_stream = true;
+ }
+} -start
+
+varnish v1 -cliok "param.set diag_bitmap 1"
+
+client c1 {
+ txreq -hdr "foo: /foo"
+ rxresp -no_obj
+
+ rxchunk
+ expect resp.chunklen == 31
+ sema r1 sync 2
+
+ rxchunk
+ expect resp.chunklen == 31
+ sema r2 sync 2
+
+ rxchunk
+ expect resp.chunklen == 31
+ sema r1 sync 2
+
+ rxchunk
+ expect resp.chunklen == 31
+ sema r2 sync 2
+
+ rxchunk
+ expect resp.chunklen == 0
+ expect resp.bodylen == 124
+} -run
More information about the varnish-commit
mailing list