r4707 - in branches/2.1: . varnish-cache/bin/varnishd varnish-cache/bin/varnishtest/tests varnish-cache/include varnish-cache/lib/libvarnish varnish-cache/lib/libvcl

tfheen at varnish-cache.org tfheen at varnish-cache.org
Wed Apr 21 12:26:07 CEST 2010


Author: tfheen
Date: 2010-04-21 12:26:07 +0200 (Wed, 21 Apr 2010)
New Revision: 4707

Added:
   branches/2.1/varnish-cache/bin/varnishtest/tests/c00034.vtc
Modified:
   branches/2.1/
   branches/2.1/varnish-cache/bin/varnishd/cache_backend.h
   branches/2.1/varnish-cache/bin/varnishd/cache_backend_cfg.c
   branches/2.1/varnish-cache/bin/varnishd/cache_response.c
   branches/2.1/varnish-cache/bin/varnishd/heritage.h
   branches/2.1/varnish-cache/bin/varnishd/mgt_param.c
   branches/2.1/varnish-cache/bin/varnishd/vparam.h
   branches/2.1/varnish-cache/bin/varnishtest/tests/c00019.vtc
   branches/2.1/varnish-cache/bin/varnishtest/tests/c00033.vtc
   branches/2.1/varnish-cache/bin/varnishtest/tests/r00325.vtc
   branches/2.1/varnish-cache/bin/varnishtest/tests/r00416.vtc
   branches/2.1/varnish-cache/bin/varnishtest/tests/r00679.vtc
   branches/2.1/varnish-cache/bin/varnishtest/tests/v00011.vtc
   branches/2.1/varnish-cache/include/vct.h
   branches/2.1/varnish-cache/include/vev.h
   branches/2.1/varnish-cache/lib/libvarnish/tcp.c
   branches/2.1/varnish-cache/lib/libvarnish/vev.c
   branches/2.1/varnish-cache/lib/libvcl/vcc_dir_random.c
Log:
Merge r4686: Add experimental and limited support for "Range:" headers.

By default it is disabled, enable with param http_range_support.




Property changes on: branches/2.1
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk:4637,4640,4643-4645,4647-4650,4654-4670
   + /trunk:4637,4640,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishd/cache_backend.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishd/cache_backend.h:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishd/cache_backend.h:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishd/cache_backend_cfg.c
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishd/cache_backend_cfg.c:4637,4643-4645,4647-4650,4654-4670,4686

Modified: branches/2.1/varnish-cache/bin/varnishd/cache_response.c
===================================================================
--- branches/2.1/varnish-cache/bin/varnishd/cache_response.c	2010-04-21 09:41:39 UTC (rev 4706)
+++ branches/2.1/varnish-cache/bin/varnishd/cache_response.c	2010-04-21 10:26:07 UTC (rev 4707)
@@ -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: branches/2.1/varnish-cache/bin/varnishd/heritage.h
===================================================================
--- branches/2.1/varnish-cache/bin/varnishd/heritage.h	2010-04-21 09:41:39 UTC (rev 4706)
+++ branches/2.1/varnish-cache/bin/varnishd/heritage.h	2010-04-21 10:26:07 UTC (rev 4707)
@@ -197,6 +197,8 @@
 	unsigned		saintmode_threshold;
 
 	unsigned		syslog_cli_traffic;
+
+	unsigned		http_range_support;
 };
 
 /*

Modified: branches/2.1/varnish-cache/bin/varnishd/mgt_param.c
===================================================================
--- branches/2.1/varnish-cache/bin/varnishd/mgt_param.c	2010-04-21 09:41:39 UTC (rev 4706)
+++ branches/2.1/varnish-cache/bin/varnishd/mgt_param.c	2010-04-21 10:26:07 UTC (rev 4707)
@@ -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: branches/2.1/varnish-cache/bin/varnishd/vparam.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishd/vparam.h:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishd/vparam.h:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/c00019.vtc
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishtest/tests/c00019.vtc:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishtest/tests/c00019.vtc:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/c00033.vtc
___________________________________________________________________
Added: svn:keywords
   + Id

Copied: branches/2.1/varnish-cache/bin/varnishtest/tests/c00034.vtc (from rev 4686, trunk/varnish-cache/bin/varnishtest/tests/c00034.vtc)
===================================================================
--- branches/2.1/varnish-cache/bin/varnishtest/tests/c00034.vtc	                        (rev 0)
+++ branches/2.1/varnish-cache/bin/varnishtest/tests/c00034.vtc	2010-04-21 10:26:07 UTC (rev 4707)
@@ -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: branches/2.1/varnish-cache/bin/varnishtest/tests/r00325.vtc
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishtest/tests/r00325.vtc:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishtest/tests/r00325.vtc:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/r00416.vtc
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishtest/tests/r00416.vtc:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishtest/tests/r00416.vtc:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/r00679.vtc
___________________________________________________________________
Added: svn:keywords
   + Id


Property changes on: branches/2.1/varnish-cache/bin/varnishtest/tests/v00011.vtc
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/bin/varnishtest/tests/v00011.vtc:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/bin/varnishtest/tests/v00011.vtc:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/include/vct.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/include/vct.h:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/include/vct.h:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/include/vev.h
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/include/vev.h:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/include/vev.h:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/lib/libvarnish/tcp.c
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/lib/libvarnish/tcp.c:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/lib/libvarnish/tcp.c:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/lib/libvarnish/vev.c
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/lib/libvarnish/vev.c:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/lib/libvarnish/vev.c:4637,4643-4645,4647-4650,4654-4670,4686


Property changes on: branches/2.1/varnish-cache/lib/libvcl/vcc_dir_random.c
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk/varnish-cache/lib/libvcl/vcc_dir_random.c:4637,4643-4645,4647-4650,4654-4670
   + /trunk/varnish-cache/lib/libvcl/vcc_dir_random.c:4637,4643-4645,4647-4650,4654-4670,4686




More information about the varnish-commit mailing list