[PATCH 05/25] Remove busyobj->h_content_length pointer into workspace

Martin Blix Grydeland martin at varnish-software.com
Sun Jan 22 18:53:11 CET 2012


The busyobj->h_content_length is a pointer to the header on the
workspace of the fetch initiating worker. This is not safe when doing
streaming.

This patch removes busyobj->h_content_length and replaces it with a
flag and an attribute instead.
---
 bin/varnishd/cache/cache.h          |    4 +++-
 bin/varnishd/cache/cache_center.c   |    3 +--
 bin/varnishd/cache/cache_fetch.c    |    9 +++++----
 bin/varnishd/cache/cache_response.c |    5 +++--
 bin/varnishd/cache/cache_rfc2616.c  |    5 +++--
 5 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 4f260e9..0bc3f59 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -523,7 +523,8 @@ struct busyobj {
 	struct vef_priv		*vef_priv;
 
 	unsigned		should_close;
-	char			*h_content_length;
+	unsigned		has_content_length;
+	ssize_t			content_length;
 
 	unsigned		do_esi;
 	unsigned		do_gzip;
@@ -768,6 +769,7 @@ int EXP_Touch(struct objcore *oc);
 int EXP_NukeOne(struct worker *w, struct lru *lru);
 
 /* cache_fetch.c */
+ssize_t FetchNumber(const char *nbr, int radix);
 struct storage *FetchStorage(struct worker *w, ssize_t sz);
 int FetchError(struct worker *w, const char *error);
 int FetchError2(struct worker *w, const char *error, const char *more);
diff --git a/bin/varnishd/cache/cache_center.c b/bin/varnishd/cache/cache_center.c
index 2909212..f074c4b 100644
--- a/bin/varnishd/cache/cache_center.c
+++ b/bin/varnishd/cache/cache_center.c
@@ -233,8 +233,7 @@ cnt_prepresp(struct sess *sp, struct worker *wrk, struct req *req)
 		wrk->res_mode |= RES_LEN;
 
 	if (wrk->busyobj != NULL &&
-	    (wrk->busyobj->h_content_length != NULL ||
-	    !wrk->busyobj->do_stream) &&
+	    (wrk->busyobj->has_content_length || !wrk->busyobj->do_stream) &&
 	    !wrk->busyobj->do_gzip && !wrk->busyobj->do_gunzip)
 		wrk->res_mode |= RES_LEN;
 
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 8cf9350..b9e7ef0 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -205,8 +205,8 @@ FetchStorage(struct worker *wrk, ssize_t sz)
  * Convert a string to a size_t safely
  */
 
-static ssize_t
-fetch_number(const char *nbr, int radix)
+ssize_t
+FetchNumber(const char *nbr, int radix)
 {
 	uintmax_t cll;
 	ssize_t cl;
@@ -291,7 +291,7 @@ fetch_chunked(struct worker *wrk, struct http_conn *htc)
 			return (FetchError(wrk,"chunked header no NL"));
 
 		buf[u] = '\0';
-		cl = fetch_number(buf, 16);
+		cl = FetchNumber(buf, 16);
 		if (cl < 0)
 			return (FetchError(wrk,"chunked header number syntax"));
 
@@ -527,7 +527,8 @@ FetchBody(struct worker *wrk, struct busyobj *bo)
 		mklen = 1;
 		break;
 	case BS_LENGTH:
-		cl = fetch_number(bo->h_content_length, 10);
+		AN(bo->has_content_length);
+		cl = bo->content_length;
 		bo->vfp->begin(wrk, cl > 0 ? cl : 0);
 		cls = fetch_straight(wrk, htc, cl);
 		mklen = 1;
diff --git a/bin/varnishd/cache/cache_response.c b/bin/varnishd/cache/cache_response.c
index 5724f07..86f4517 100644
--- a/bin/varnishd/cache/cache_response.c
+++ b/bin/varnishd/cache/cache_response.c
@@ -353,9 +353,10 @@ RES_StreamStart(struct sess *sp)
 		http_Unset(sp->req->resp, H_Content_Encoding);
 
 	if (!(sp->wrk->res_mode & RES_CHUNKED) &&
-	    sp->wrk->busyobj->h_content_length != NULL)
+	    sp->wrk->busyobj->has_content_length &&
+	    !http_GetHdr(sp->req->resp, H_Content_Length, NULL))
 		http_PrintfHeader(sp->wrk, sp->vsl_id, sp->req->resp,
-		    "Content-Length: %s", sp->wrk->busyobj->h_content_length);
+		    "Content-Length: %zd", sp->wrk->busyobj->content_length);
 
 	sp->wrk->acct_tmp.hdrbytes +=
 	    http_Write(sp->wrk, sp->vsl_id, sp->req->resp, 1);
diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c
index 1b67d81..59d4e2c 100644
--- a/bin/varnishd/cache/cache_rfc2616.c
+++ b/bin/varnishd/cache/cache_rfc2616.c
@@ -239,8 +239,9 @@ RFC2616_Body(const struct sess *sp)
 		return (BS_ERROR);
 	}
 
-	if (http_GetHdr(hp, H_Content_Length,
-	    &sp->wrk->busyobj->h_content_length)) {
+	if (http_GetHdr(hp, H_Content_Length, &b)) {
+		sp->wrk->busyobj->has_content_length = 1;
+		sp->wrk->busyobj->content_length = FetchNumber(b, 10);
 		sp->wrk->stats.fetch_length++;
 		return (BS_LENGTH);
 	}
-- 
1.7.4.1




More information about the varnish-dev mailing list