[7.6] 383278e98 v1f: pull chunk header parsing into an own function

Walid Boudebouda walid.boudebouda at gmail.com
Mon May 12 15:29:05 UTC 2025


commit 383278e98fa4e74c0f396431449bb4bd729b563d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Mon May 30 13:42:58 2022 +0200

    v1f: pull chunk header parsing into an own function
    
    ... which we are going to need in a follow up commit.
    
    No functional changes, diff best viewed with -b

diff --git a/bin/varnishd/http1/cache_http1_vfp.c b/bin/varnishd/http1/cache_http1_vfp.c
index aceb5a628..d684f1043 100644
--- a/bin/varnishd/http1/cache_http1_vfp.c
+++ b/bin/varnishd/http1/cache_http1_vfp.c
@@ -108,76 +108,98 @@ v1f_chunk_end(struct vfp_ctx *vc, struct http_conn *htc)
 
 
 /*--------------------------------------------------------------------
- * Read a chunked HTTP object.
+ * Parse a chunk header and, for VFP_OK, return size in a pointer
  *
  * XXX: Reading one byte at a time is pretty pessimal.
  */
 
-static enum vfp_status v_matchproto_(vfp_pull_f)
-v1f_chunked_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr,
-    ssize_t *lp)
+static enum vfp_status
+v1f_chunked_hdr(struct vfp_ctx *vc, struct http_conn *htc, ssize_t *szp)
 {
-	static enum vfp_status vfps;
-	struct http_conn *htc;
 	char buf[20];		/* XXX: 20 is arbitrary */
-	char *q;
 	unsigned u;
 	uintmax_t cll;
-	ssize_t cl, l, lr;
+	ssize_t cl, lr;
+	char *q;
 
 	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
-	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
-	CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC);
-	AN(ptr);
-	AN(lp);
+	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+	AN(szp);
+	assert(*szp == -1);
 
-	l = *lp;
-	*lp = 0;
-	if (vfe->priv2 == -1) {
-		/* Skip leading whitespace */
-		do {
-			lr = v1f_read(vc, htc, buf, 1);
-			if (lr <= 0)
-				return (VFP_Error(vc, "chunked read err"));
-		} while (vct_islws(buf[0]));
-
-		if (!vct_ishex(buf[0]))
-			 return (VFP_Error(vc, "chunked header non-hex"));
-
-		/* Collect hex digits, skipping leading zeros */
-		for (u = 1; u < sizeof buf; u++) {
-			do {
-				lr = v1f_read(vc, htc, buf + u, 1);
-				if (lr <= 0)
-					return (VFP_Error(vc, "chunked read err"));
-			} while (u == 1 && buf[0] == '0' && buf[u] == '0');
-			if (!vct_ishex(buf[u]))
-				break;
-		}
+	/* Skip leading whitespace */
+	do {
+		lr = v1f_read(vc, htc, buf, 1);
+		if (lr <= 0)
+			return (VFP_Error(vc, "chunked read err"));
+	} while (vct_islws(buf[0]));
 
-		if (u >= sizeof buf)
-			return (VFP_Error(vc, "chunked header too long"));
+	if (!vct_ishex(buf[0]))
+		return (VFP_Error(vc, "chunked header non-hex"));
 
-		/* Skip trailing white space */
-		while (vct_islws(buf[u]) && buf[u] != '\n') {
+	/* Collect hex digits, skipping leading zeros */
+	for (u = 1; u < sizeof buf; u++) {
+		do {
 			lr = v1f_read(vc, htc, buf + u, 1);
 			if (lr <= 0)
 				return (VFP_Error(vc, "chunked read err"));
-		}
+		} while (u == 1 && buf[0] == '0' && buf[u] == '0');
+		if (!vct_ishex(buf[u]))
+			break;
+	}
 
-		if (buf[u] != '\n')
-			return (VFP_Error(vc, "chunked header no NL"));
+	if (u >= sizeof buf)
+		return (VFP_Error(vc, "chunked header too long"));
+
+	/* Skip trailing white space */
+	while (vct_islws(buf[u]) && buf[u] != '\n') {
+		lr = v1f_read(vc, htc, buf + u, 1);
+		if (lr <= 0)
+			return (VFP_Error(vc, "chunked read err"));
+	}
 
-		buf[u] = '\0';
+	if (buf[u] != '\n')
+		return (VFP_Error(vc, "chunked header no NL"));
 
-		cll = strtoumax(buf, &q, 16);
-		if (q == NULL || *q != '\0')
-			return (VFP_Error(vc, "chunked header number syntax"));
-		cl = (ssize_t)cll;
-		if (cl < 0 || (uintmax_t)cl != cll)
-			return (VFP_Error(vc, "bogusly large chunk size"));
+	buf[u] = '\0';
 
-		vfe->priv2 = cl;
+	cll = strtoumax(buf, &q, 16);
+	if (q == NULL || *q != '\0')
+		return (VFP_Error(vc, "chunked header number syntax"));
+	cl = (ssize_t)cll;
+	if (cl < 0 || (uintmax_t)cl != cll)
+		return (VFP_Error(vc, "bogusly large chunk size"));
+
+	*szp = cl;
+	return (VFP_OK);
+}
+
+
+/*--------------------------------------------------------------------
+ * Read a chunked HTTP object.
+ *
+ */
+
+static enum vfp_status v_matchproto_(vfp_pull_f)
+v1f_chunked_pull(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr,
+    ssize_t *lp)
+{
+	static enum vfp_status vfps;
+	struct http_conn *htc;
+	ssize_t l, lr;
+
+	CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC);
+	CAST_OBJ_NOTNULL(htc, vfe->priv1, HTTP_CONN_MAGIC);
+	AN(ptr);
+	AN(lp);
+
+	l = *lp;
+	*lp = 0;
+	if (vfe->priv2 == -1) {
+		vfps = v1f_chunked_hdr(vc, htc, &vfe->priv2);
+		if (vfps != VFP_OK)
+			return (vfps);
 	}
 	if (vfe->priv2 > 0) {
 		if (vfe->priv2 < l)


More information about the varnish-commit mailing list