MINOR: cache: Add "max-object-size" option.

This patch adds "max-object-size" option to the cache to limit
the size in bytes of the HTTP objects to be cached. When not provided,
the maximum size of an HTTP object is a 256th of the cache size.
diff --git a/src/cache.c b/src/cache.c
index c0e8957..d241154 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -50,6 +50,7 @@
 	struct eb_root entries;  /* head of cache entries based on keys */
 	unsigned int maxage;     /* max-age */
 	unsigned int maxblocks;
+	unsigned int maxobjsz;   /* max-object-size */
 	char id[33];             /* cache name */
 };
 
@@ -230,9 +231,6 @@
 
 			to_append = MIN(ci_contig_data(msg->chn), len - st->hdrs_len);
 
-			/* Skip remaining headers to fill the cache */
-			c_adv(msg->chn, st->hdrs_len);
-
 			shctx_lock(shctx);
 			fb = shctx_row_reserve_hot(shctx, st->first_block, to_append);
 			if (!fb) {
@@ -242,6 +240,8 @@
 			}
 			shctx_unlock(shctx);
 
+			/* Skip remaining headers to fill the cache */
+			c_adv(msg->chn, st->hdrs_len);
 			append = shctx_row_data_append(shctx, st->first_block, st->first_block->last_append,
 			                               (unsigned char *)ci_head(msg->chn), to_append);
 			ret = st->hdrs_len + to_append - append;
@@ -431,6 +431,11 @@
 	if (!(txn->req.flags & HTTP_MSGF_VER_11))
 		goto out;
 
+	/* Do not cache too big objects. */
+	if ((msg->flags & HTTP_MSGF_CNT_LEN) && shctx->max_obj_size > 0 &&
+	    msg->sov + msg->body_len > shctx->max_obj_size)
+		goto out;
+
 	/* cache only GET method */
 	if (txn->meth != HTTP_METH_GET)
 		goto out;
@@ -830,6 +835,7 @@
 			}
 			tmp_cache_config->maxage = 60;
 			tmp_cache_config->maxblocks = 0;
+			tmp_cache_config->maxobjsz = 0;
 		}
 	} else if (strcmp(args[0], "total-max-size") == 0) {
 		int maxsize;
@@ -856,7 +862,21 @@
 		}
 
 		tmp_cache_config->maxage = atoi(args[1]);
-	} else if (*args[0] != 0) {
+	} else if (strcmp(args[0], "max-object-size") == 0) {
+		if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
+			err_code |= ERR_ABORT;
+			goto out;
+		}
+
+		if (!*args[1]) {
+			ha_warning("parsing [%s:%d]: '%s' expects a maximum file size parameter in bytes.\n",
+			        file, linenum, args[0]);
+			err_code |= ERR_WARN;
+		}
+
+		tmp_cache_config->maxobjsz = atoi(args[1]);
+	}
+	else if (*args[0] != 0) {
 		ha_alert("parsing [%s:%d] : unknown keyword '%s' in 'cache' section\n", file, linenum, args[0]);
 		err_code |= ERR_ALERT | ERR_FATAL;
 		goto out;
@@ -882,7 +902,13 @@
 			goto out;
 		}
 
-		ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, -1, sizeof(struct cache), 1);
+		if (!tmp_cache_config->maxobjsz)
+			/* Default max. file size is a 256th of the cache size. */
+			tmp_cache_config->maxobjsz =
+				(tmp_cache_config->maxblocks * CACHE_BLOCKSIZE) >> 8;
+
+		ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE,
+		                       tmp_cache_config->maxobjsz, sizeof(struct cache), 1);
 
 		if (ret_shctx < 0) {
 			if (ret_shctx == SHCTX_E_INIT_LOCK)