Introduction
Introduction Statistics Contact Development Disclaimer Help
check received content length if the Content-Length header is set - hurl - Goph…
git clone git://git.codemadness.org/hurl
Log
Files
Refs
README
LICENSE
---
commit 85d6ee233ea16724799840840cb19c955cc0842f
parent a931b2c32a110fc26258afe16cc77d1c7f5d1e44
Author: Hiltjo Posthuma <[email protected]>
Date: Mon, 9 Aug 2021 18:54:46 +0200
check received content length if the Content-Length header is set
This prevents corrupted downloads, noticed when my connection was crappy.
Diffstat:
M hurl.c | 58 ++++++++++++++++++++++++++---…
1 file changed, 50 insertions(+), 8 deletions(-)
---
diff --git a/hurl.c b/hurl.c
@@ -64,6 +64,32 @@ sighandler(int signo)
}
int
+parse_content_length(const char *s, size_t *length)
+{
+ const char *p;
+ char *end;
+ long long l;
+
+ if (!(p = strcasestr(s, "\r\nContent-Length:")))
+ return -1;
+
+ p += sizeof("\r\nContent-Length:") - 1;
+ p += strspn(p, " \t");
+
+ if (!isdigit(*p))
+ return -1;
+
+ errno = 0;
+ l = strtoll(p, &end, 10);
+ if (errno || p == end || (*end != '\0' && *end != '\r') || l < 0)
+ return -1;
+
+ *length = l;
+
+ return 0;
+}
+
+int
uri_parse(const char *s, struct uri *u)
{
const char *p = s;
@@ -221,9 +247,9 @@ https_request(void)
struct tls *t;
char buf[READ_BUF_SIZ], *p;
const char *errstr;
- size_t n, len;
+ size_t bodylen, expectedlen, n, len;
ssize_t r;
- int fd = -1, httpok = 0, ret = 1, stdport;
+ int cs, fd = -1, httpok = 0, ret = 1, stdport;
if (pledge("stdio dns inet rpath unveil", NULL) == -1)
err(1, "pledge");
@@ -308,7 +334,9 @@ https_request(void)
goto err;
}
*p = '\0'; /* NUL terminate header part */
+ cs = parse_content_length(buf, &expectedlen);
p += strlen("\r\n\r\n");
+ bodylen = strlen(p); /* (partial) body after header */
if (httpok) {
n = len - (p - buf);
@@ -336,6 +364,7 @@ https_request(void)
goto err;
}
len += r;
+ bodylen += r;
if (httpok) {
r = fwrite(buf, 1, r, stdout);
@@ -349,10 +378,15 @@ https_request(void)
break;
}
if (config_maxresponsesiz && len >= config_maxresponsesiz) {
- fprintf(stderr, "tls_read: response too big: %zu >= %zu\n",
+ fprintf(stderr, "response too big: %zu >= %zu\n",
len, config_maxresponsesiz);
goto err;
}
+ if (cs != -1 && expectedlen != bodylen) {
+ fprintf(stderr, "Content-Length mismatch: %zu expected != %zu …
+ expectedlen, bodylen);
+ goto err;
+ }
ret = 0;
err:
@@ -368,9 +402,9 @@ int
http_request(void)
{
char buf[READ_BUF_SIZ], *p;
- size_t n, len;
+ size_t bodylen, expectedlen, n, len;
ssize_t r;
- int fd = -1, httpok = 0, ret = 1, stdport;
+ int cs, fd = -1, httpok = 0, ret = 1, stdport;
if (pledge("stdio dns inet", NULL) == -1)
err(1, "pledge");
@@ -426,7 +460,9 @@ http_request(void)
goto err;
}
*p = '\0'; /* NUL terminate header part */
+ cs = parse_content_length(buf, &expectedlen);
p += strlen("\r\n\r\n");
+ bodylen = strlen(p); /* (partial) body after header */
if (httpok) {
n = len - (p - buf);
@@ -451,6 +487,7 @@ http_request(void)
goto err;
}
len += r;
+ bodylen += r;
if (httpok) {
r = fwrite(buf, 1, r, stdout);
@@ -464,10 +501,15 @@ http_request(void)
break;
}
if (config_maxresponsesiz && len >= config_maxresponsesiz) {
- fprintf(stderr, "read: response too big: %zu >= %zu\n",
+ fprintf(stderr, "response too big: %zu >= %zu\n",
len, config_maxresponsesiz);
goto err;
}
+ if (cs != -1 && expectedlen != bodylen) {
+ fprintf(stderr, "Content-Length mismatch: %zu expected != %zu …
+ expectedlen, bodylen);
+ goto err;
+ }
ret = 0;
err:
@@ -534,7 +576,7 @@ gopher_request(void)
break;
}
if (config_maxresponsesiz && len >= config_maxresponsesiz) {
- fprintf(stderr, "read: response too big: %zu >= %zu\n",
+ fprintf(stderr, "response too big: %zu >= %zu\n",
len, config_maxresponsesiz);
goto err;
}
@@ -633,7 +675,7 @@ gophers_request(void)
break;
}
if (config_maxresponsesiz && len >= config_maxresponsesiz) {
- fprintf(stderr, "read: response too big: %zu >= %zu\n",
+ fprintf(stderr, "response too big: %zu >= %zu\n",
len, config_maxresponsesiz);
goto err;
}
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.