aboutsummaryrefslogtreecommitdiff
path: root/lib/libfetch
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2004-02-27 10:24:59 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2004-02-27 10:24:59 +0000
commit6cbb108abc0159b0cc0502afe7261b6305f014a4 (patch)
treecaf04fe12e143389eaf783a5b6cbb758966eb40a /lib/libfetch
parent965e9efdfaf4bc456fa575ca5f2d41df01a641e6 (diff)
Notes
Diffstat (limited to 'lib/libfetch')
-rw-r--r--lib/libfetch/http.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index 86f7075268fd..8d2f971000e4 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
#define HTTP_SEE_OTHER 303
#define HTTP_NEED_AUTH 401
#define HTTP_NEED_PROXY_AUTH 407
+#define HTTP_BAD_RANGE 416
#define HTTP_PROTOCOL_ERROR 999
#define HTTP_REDIRECT(xyz) ((xyz) == HTTP_MOVED_PERM \
@@ -513,22 +514,34 @@ _http_parse_range(const char *p, off_t *offset, off_t *length, off_t *size)
if (strncasecmp(p, "bytes ", 6) != 0)
return (-1);
- for (first = 0, p += 6; *p && isdigit(*p); ++p)
- first = first * 10 + *p - '0';
- if (*p != '-')
- return (-1);
- for (last = 0, ++p; *p && isdigit(*p); ++p)
- last = last * 10 + *p - '0';
+ p += 6;
+ if (*p == '*') {
+ first = last = -1;
+ ++p;
+ } else {
+ for (first = 0; *p && isdigit(*p); ++p)
+ first = first * 10 + *p - '0';
+ if (*p != '-')
+ return (-1);
+ for (last = 0, ++p; *p && isdigit(*p); ++p)
+ last = last * 10 + *p - '0';
+ }
if (first > last || *p != '/')
return (-1);
for (len = 0, ++p; *p && isdigit(*p); ++p)
len = len * 10 + *p - '0';
if (*p || len < last - first + 1)
return (-1);
- DEBUG(fprintf(stderr, "content range: [%lld-%lld/%lld]\n",
- (long long)first, (long long)last, (long long)len));
+ if (first == -1) {
+ DEBUG(fprintf(stderr, "content range: [*/%lld]\n",
+ (long long)len));
+ *length = 0;
+ } else {
+ DEBUG(fprintf(stderr, "content range: [%lld-%lld/%lld]\n",
+ (long long)first, (long long)last, (long long)len));
+ *length = last - first + 1;
+ }
*offset = first;
- *length = last - first + 1;
*size = len;
return (0);
}
@@ -904,15 +917,15 @@ _http_request(struct url *URL, const char *op, struct url_stat *us,
case HTTP_MOVED_TEMP:
case HTTP_SEE_OTHER:
/*
- * Not so fine, but we still have to read the headers to
- * get the new location.
+ * Not so fine, but we still have to read the
+ * headers to get the new location.
*/
break;
case HTTP_NEED_AUTH:
if (need_auth) {
/*
- * We already sent out authorization code, so there's
- * nothing more we can do.
+ * We already sent out authorization code,
+ * so there's nothing more we can do.
*/
_http_seterr(conn->err);
goto ouch;
@@ -923,11 +936,19 @@ _http_request(struct url *URL, const char *op, struct url_stat *us,
break;
case HTTP_NEED_PROXY_AUTH:
/*
- * If we're talking to a proxy, we already sent our proxy
- * authorization code, so there's nothing more we can do.
+ * If we're talking to a proxy, we already sent
+ * our proxy authorization code, so there's
+ * nothing more we can do.
*/
_http_seterr(conn->err);
goto ouch;
+ case HTTP_BAD_RANGE:
+ /*
+ * This can happen if we ask for 0 bytes because
+ * we already have the whole file. Consider this
+ * a success for now, and check sizes later.
+ */
+ break;
case HTTP_PROTOCOL_ERROR:
/* fall through */
case -1:
@@ -1009,6 +1030,19 @@ _http_request(struct url *URL, const char *op, struct url_stat *us,
continue;
}
+ /* requested range not satisfiable */
+ if (conn->err == HTTP_BAD_RANGE) {
+ if (url->offset == size && url->length == 0) {
+ /* asked for 0 bytes; fake it */
+ offset = url->offset;
+ conn->err = HTTP_OK;
+ break;
+ } else {
+ _http_seterr(conn->err);
+ goto ouch;
+ }
+ }
+
/* we have a hit or an error */
if (conn->err == HTTP_OK || conn->err == HTTP_PARTIAL || HTTP_ERROR(conn->err))
break;