[master] acd2cd05d http: Extract vrg_dorange parsing in http_GetRange()

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Tue Aug 31 10:23:06 UTC 2021


commit acd2cd05d029ee33f60c1ed2c1a86e8d5ce4b339
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Mon Aug 23 10:36:24 2021 +0200

    http: Extract vrg_dorange parsing in http_GetRange()

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 31fdd4d1f..245b7aa98 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -607,6 +607,7 @@ int http_GetHdrField(const struct http *hp, hdr_t,
 double http_GetHdrQ(const struct http *hp, hdr_t, const char *field);
 ssize_t http_GetContentLength(const struct http *hp);
 ssize_t http_GetContentRange(const struct http *hp, ssize_t *lo, ssize_t *hi);
+const char * http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi);
 uint16_t http_GetStatus(const struct http *hp);
 int http_IsStatus(const struct http *hp, int);
 void http_SetStatus(struct http *to, uint16_t status, const char *reason);
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 7819c383d..005a5ac04 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -832,11 +832,11 @@ http_parse_uint(const char *b, const char **e)
 		return (-1);
 	for (; vct_isdigit(*b); b++) {
 		if (u > (SSIZE_MAX / 10))
-			return (-1);
+			return (-2);
 		u *= 10;
 		n = *b - '0';
 		if (u > (SSIZE_MAX - n))
-			return (-1);
+			return (-2);
 		u += n;
 	}
 
@@ -928,6 +928,51 @@ http_GetContentRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
 	return (cl);
 }
 
+const char *
+http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
+{
+	ssize_t tmp;
+	const char *b;
+
+	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+
+	if (lo == NULL)
+		lo = &tmp;
+	if (hi == NULL)
+		hi = &tmp;
+
+	*lo = *hi = -1;
+
+	if (!http_GetHdr(hp, H_Range, &b))
+		return (NULL);
+
+	if (!http_range_at(b, bytes=))
+		return ("Not Bytes");
+	b += strlen("bytes=");
+
+	*lo = http_parse_uint(b, &b);
+	if (*lo == -2)
+		return ("Low number too big");
+	if (*b++ != '-')
+		return ("Missing hyphen");
+
+	*hi = http_parse_uint(b, &b);
+	if (*hi == -2)
+		return ("High number too big");
+	if (*lo == -1 && *hi == -1)
+		return ("Neither high nor low");
+	if (*lo == -1 && *hi == 0)
+		return ("No low, high is zero");
+	if (*hi >= 0 && *hi < *lo)
+		return ("high smaller than low");
+
+	while (vct_islws(*b))
+		b++;
+	if (*b != '\0')
+		return ("Trailing stuff");
+	return (NULL);
+}
+
 /*--------------------------------------------------------------------
  */
 
diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c
index 7451c3812..75c434a94 100644
--- a/bin/varnishd/cache/cache_range.c
+++ b/bin/varnishd/cache/cache_range.c
@@ -103,58 +103,30 @@ vrg_range_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
 /*--------------------------------------------------------------------*/
 
 static const char *
-vrg_dorange(struct req *req, const char *r, void **priv)
+vrg_dorange(struct req *req, void **priv)
 {
-	ssize_t low, high, has_low, has_high, t;
+	ssize_t low, high;
 	struct vrg_priv *vrg_priv;
+	const char *err;
 
-	if (!http_range_at(r, bytes=))
-		return ("Not Bytes");
-	r += 6;
-
-	/* The low end of range */
-	has_low = low = 0;
-	while (vct_isdigit(*r)) {
-		has_low = 1;
-		t = low;
-		low *= 10;
-		low += *r++ - '0';
-		if (low < t)
-			return ("Low number too big");
-	}
-
-	if (*r++ != '-')
-		return ("Missing hyphen");
-
-	/* The high end of range */
-	has_high = high = 0;
-	while (vct_isdigit(*r)) {
-		has_high = 1;
-		t = high;
-		high *= 10;
-		high += *r++ - '0';
-		if (high < t)
-			return ("High number too big");
-	}
-
-	if (*r != '\0')
-		return ("Trailing stuff");
+	err = http_GetRange(req->http, &low, &high);
+	if (err != NULL)
+		return (err);
 
-	if (has_high + has_low == 0)
-		return ("Neither high nor low");
+	assert(low >= -1);
+	assert(high >= -1);
 
-	if (!has_low) {
+	if (low < 0) {
 		if (req->resp_len < 0)
 			return (NULL);		// Allow 200 response
-		if (high == 0)
-			return ("No low, high is zero");
+		assert(high > 0);
 		low = req->resp_len - high;
 		if (low < 0)
 			low = 0;
 		high = req->resp_len - 1;
-	} else if (req->resp_len >= 0 && (high >= req->resp_len || !has_high))
+	} else if (req->resp_len >= 0 && (high >= req->resp_len || high < 0))
 		high = req->resp_len - 1;
-	else if (!has_high || req->resp_len < 0)
+	else if (high < 0 || req->resp_len < 0)
 		return (NULL);			// Allow 200 response
 	/*
 	 * else (bo != NULL) {
@@ -163,9 +135,6 @@ vrg_dorange(struct req *req, const char *r, void **priv)
 	 * }
 	 */
 
-	if (high < low)
-		return ("high smaller than low");
-
 	if (req->resp_len >= 0 && low >= req->resp_len)
 		return ("low range beyond object");
 
@@ -252,7 +221,6 @@ vrg_ifrange(struct req *req)
 static int v_matchproto_(vdp_init_f)
 vrg_range_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc)
 {
-	const char *r;
 	const char *err;
 	struct req *req;
 
@@ -260,10 +228,10 @@ vrg_range_init(struct vdp_ctx *vdc, void **priv, struct objcore *oc)
 	(void)oc;
 	req = vdc->req;
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-	assert(http_GetHdr(req->http, H_Range, &r));
+	assert(http_GetHdr(req->http, H_Range, NULL));
 	if (!vrg_ifrange(req))		// rfc7233,l,455,456
 		return (1);
-	err = vrg_dorange(req, r, priv);
+	err = vrg_dorange(req, priv);
 	if (err == NULL)
 		return (*priv == NULL ? 1 : 0);
 


More information about the varnish-commit mailing list