r4686 - in trunk/varnish-cache/bin: varnishd varnishtest/tests
phk at varnish-cache.org
phk at varnish-cache.org
Mon Apr 19 13:58:33 CEST 2010
Author: phk
Date: 2010-04-19 13:58:33 +0200 (Mon, 19 Apr 2010)
New Revision: 4686
Added:
trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc
Modified:
trunk/varnish-cache/bin/varnishd/cache_response.c
trunk/varnish-cache/bin/varnishd/heritage.h
trunk/varnish-cache/bin/varnishd/mgt_param.c
trunk/varnish-cache/bin/varnishtest/tests/c00032.vtc
trunk/varnish-cache/bin/varnishtest/tests/c00033.vtc
trunk/varnish-cache/bin/varnishtest/tests/r00679.vtc
Log:
Add experimental and limited support for "Range:" headers.
By default it is disabled, enable with param http_range_support.
Modified: trunk/varnish-cache/bin/varnishd/cache_response.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_response.c 2010-04-19 11:54:32 UTC (rev 4685)
+++ trunk/varnish-cache/bin/varnishd/cache_response.c 2010-04-19 11:58:33 UTC (rev 4686)
@@ -40,6 +40,7 @@
#include "shmlog.h"
#include "cache.h"
+#include "vct.h"
/*--------------------------------------------------------------------*/
@@ -127,6 +128,56 @@
/*--------------------------------------------------------------------*/
+static void
+res_dorange(struct sess *sp, const char *r, unsigned *plow, unsigned *phigh)
+{
+ unsigned low, high;
+
+ (void)sp;
+ if (strncmp(r, "bytes=", 6))
+ return;
+ r += 6;
+ printf("-----------------RANGE: <%s>\n", r);
+ low = 0;
+ high = 0;
+ if (!vct_isdigit(*r))
+ return;
+ while (vct_isdigit(*r)) {
+ low *= 10;
+ low += *r - '0';
+ r++;
+ }
+ if (*r != '-')
+ return;
+ r++;
+ if (!vct_isdigit(*r))
+ return;
+ while (vct_isdigit(*r)) {
+ high *= 10;
+ high += *r - '0';
+ r++;
+ }
+ if (*r != '\0')
+ return;
+ printf("-----------------RANGE: %u %u\n", low, high);
+ if (high >= sp->obj->len)
+ high = sp->obj->len - 1;
+ if (low == 0 && high >= sp->obj->len)
+ return;
+
+
+ http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp,
+ "Content-Range: bytes %u-%u/%u", low, high, sp->obj->len);
+ http_Unset(sp->wrk->resp, H_Content_Length);
+ http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp,
+ "Content-Length: %u", 1 + high - low);
+ http_SetResp(sp->wrk->resp, "HTTP/1.1", "206", "Partial Content");
+ *plow = low;
+ *phigh = high;
+}
+
+/*--------------------------------------------------------------------*/
+
void
RES_BuildHttp(struct sess *sp)
{
@@ -153,7 +204,10 @@
"Transfer-Encoding: chunked");
else
sp->doclose = "ESI EOF";
- }
+ } else if (params->http_range_support)
+ http_SetHeader(sp->wrk, sp->fd, sp->wrk->resp,
+ "Accept-Ranges: bytes");
+
TIM_format(TIM_real(), time_str);
http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp, "Date: %s", time_str);
@@ -179,63 +233,119 @@
struct storage *st;
unsigned u = 0;
char lenbuf[20];
+ char *r;
+ unsigned low, high, ptr, off, len;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
WRW_Reserve(sp->wrk, &sp->fd);
- if (sp->disable_esi || !sp->esis)
- sp->acct_req.hdrbytes += http_Write(sp->wrk, sp->wrk->resp, 1);
+ /*
+ * ESI objects get special delivery
+ */
+ if (!sp->disable_esi && sp->obj->esidata != NULL) {
- if (!sp->disable_esi && sp->wantbody && sp->obj->esidata != NULL) {
+ if (sp->esis == 0)
+ /* no headers for interior ESI includes */
+ sp->acct_req.hdrbytes +=
+ http_Write(sp->wrk, sp->wrk->resp, 1);
+
if (WRW_FlushRelease(sp->wrk)) {
vca_close_session(sp, "remote closed");
- return;
- }
- ESI_Deliver(sp);
+ } else if (sp->wantbody)
+ ESI_Deliver(sp);
return;
}
- if (sp->wantbody) {
- if (!sp->disable_esi &&
- sp->esis > 0 &&
- sp->http->protover >= 1.1 &&
- sp->obj->len > 0) {
- sprintf(lenbuf, "%x\r\n", sp->obj->len);
- (void)WRW_Write(sp->wrk, lenbuf, -1);
+ /*
+ * How much of the object we want to deliver
+ */
+ low = 0;
+ high = sp->obj->len - 1;
+
+ if (sp->disable_esi || sp->esis == 0) {
+ /* For none ESI and non ESI-included objects, try Range */
+ if (params->http_range_support &&
+ (sp->disable_esi || sp->esis == 0) &&
+ sp->obj->response == 200 &&
+ sp->wantbody &&
+ http_GetHdr(sp->http, H_Range, &r))
+ res_dorange(sp, r, &low, &high);
+
+ sp->acct_req.hdrbytes += http_Write(sp->wrk, sp->wrk->resp, 1);
+ } else if (!sp->disable_esi &&
+ sp->esis > 0 &&
+ sp->http->protover >= 1.1 &&
+ sp->obj->len > 0) {
+ /*
+ * Interior ESI includes (which are not themselves ESI
+ * objects) use chunked encoding (here) or EOF (nothing)
+ */
+ assert(sp->wantbody);
+ sprintf(lenbuf, "%x\r\n", sp->obj->len);
+ (void)WRW_Write(sp->wrk, lenbuf, -1);
+ }
+
+ if (!sp->wantbody) {
+ /* This was a HEAD request */
+ assert(sp->esis == 0);
+ if (WRW_FlushRelease(sp->wrk))
+ vca_close_session(sp, "remote closed");
+ return;
+ }
+
+ ptr = 0;
+ VTAILQ_FOREACH(st, &sp->obj->store, list) {
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+ u += st->len;
+ len = st->len;
+ off = 0;
+ if (ptr + len <= low) {
+ /* This segment is too early */
+ ptr += len;
+ continue;
}
+ if (ptr < low) {
+ /* Chop front of segment off */
+ off += (low - ptr);
+ len -= (low - ptr);
+ ptr += (low - ptr);
+ }
+ if (ptr + len > high)
+ /* Chop tail of segment off */
+ len = 1 + high - low;
- VTAILQ_FOREACH(st, &sp->obj->store, list) {
- CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
- u += st->len;
- sp->acct_req.bodybytes += st->len;
+ ptr += len;
+
+ sp->acct_req.bodybytes += len;
#ifdef SENDFILE_WORKS
- /*
- * XXX: the overhead of setting up sendfile is not
- * XXX: epsilon and maybe not even delta, so avoid
- * XXX: engaging sendfile for small objects.
- * XXX: Should use getpagesize() ?
- */
- if (st->fd >= 0 &&
- st->len >= params->sendfile_threshold) {
- VSL_stats->n_objsendfile++;
- WRW_Sendfile(sp->wrk, st->fd,
- st->where, st->len);
- continue;
- }
+ /*
+ * XXX: the overhead of setting up sendfile is not
+ * XXX: epsilon and maybe not even delta, so avoid
+ * XXX: engaging sendfile for small objects.
+ * XXX: Should use getpagesize() ?
+ */
+ if (st->fd >= 0 &&
+ st->len >= params->sendfile_threshold) {
+ VSL_stats->n_objsendfile++;
+ WRW_Sendfile(sp->wrk, st->fd, st->where + off, len);
+ continue;
+ }
#endif /* SENDFILE_WORKS */
- VSL_stats->n_objwrite++;
- (void)WRW_Write(sp->wrk, st->ptr, st->len);
- }
- assert(u == sp->obj->len);
- if (!sp->disable_esi &&
- sp->esis > 0 &&
- sp->http->protover >= 1.1 &&
- sp->obj->len > 0)
- (void)WRW_Write(sp->wrk, "\r\n", -1);
+ VSL_stats->n_objwrite++;
+ (void)WRW_Write(sp->wrk, st->ptr + off, len);
}
+ assert(u == sp->obj->len);
+ if (!sp->disable_esi &&
+ sp->esis > 0 &&
+ sp->http->protover >= 1.1 &&
+ sp->obj->len > 0) {
+ /* post-chunk new line */
+ (void)WRW_Write(sp->wrk, "\r\n", -1);
+ }
+
if (WRW_FlushRelease(sp->wrk))
vca_close_session(sp, "remote closed");
}
Modified: trunk/varnish-cache/bin/varnishd/heritage.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/heritage.h 2010-04-19 11:54:32 UTC (rev 4685)
+++ trunk/varnish-cache/bin/varnishd/heritage.h 2010-04-19 11:58:33 UTC (rev 4686)
@@ -197,6 +197,8 @@
unsigned saintmode_threshold;
unsigned syslog_cli_traffic;
+
+ unsigned http_range_support;
};
/*
Modified: trunk/varnish-cache/bin/varnishd/mgt_param.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-04-19 11:54:32 UTC (rev 4685)
+++ trunk/varnish-cache/bin/varnishd/mgt_param.c 2010-04-19 11:58:33 UTC (rev 4686)
@@ -813,6 +813,10 @@
"A value of 0 disables saintmode.",
EXPERIMENTAL,
"10", "objects" },
+ { "http_range_support", tweak_bool, &master.http_range_support, 0, 0,
+ "Enable support for HTTP Range headers.\n",
+ EXPERIMENTAL,
+ "off", "bool" },
{ NULL, NULL, NULL }
};
Property changes on: trunk/varnish-cache/bin/varnishtest/tests/c00032.vtc
___________________________________________________________________
Added: svn:keywords
+ Id
Property changes on: trunk/varnish-cache/bin/varnishtest/tests/c00033.vtc
___________________________________________________________________
Added: svn:keywords
+ Id
Added: trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc
===================================================================
--- trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc (rev 0)
+++ trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc 2010-04-19 11:58:33 UTC (rev 4686)
@@ -0,0 +1,59 @@
+# $Id$
+
+test "Range headers"
+
+server s1 {
+ rxreq
+ txresp -bodylen 100
+} -start
+
+varnish v1 -vcl+backend {
+} -start
+
+client c1 {
+ txreq -hdr "Range: bytes=0-9"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 100
+} -run
+
+varnish v1 -cliok "param.set http_range_support on"
+
+
+client c1 {
+ txreq -hdr "Range: bytes =0-9"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 100
+
+ txreq -hdr "Range: bytes=0- 9"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 100
+
+ txreq -hdr "Range: bytes =-9"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 100
+
+ txreq -hdr "Range: bytes =0-a"
+ rxresp
+ expect resp.status == 200
+ expect resp.bodylen == 100
+
+ txreq -hdr "Range: bytes=0-9"
+ rxresp
+ expect resp.status == 206
+ expect resp.bodylen == 10
+
+ txreq -hdr "Range: bytes=10-19"
+ rxresp
+ expect resp.status == 206
+ expect resp.bodylen == 10
+
+ txreq -hdr "Range: bytes=90-101"
+ rxresp
+ expect resp.status == 206
+ expect resp.bodylen == 10
+} -run
+
Property changes on: trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc
___________________________________________________________________
Added: svn:keywords
+ Id
Property changes on: trunk/varnish-cache/bin/varnishtest/tests/r00679.vtc
___________________________________________________________________
Added: svn:keywords
+ Id
More information about the varnish-commit
mailing list