[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