diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2004-02-27 10:24:59 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2004-02-27 10:24:59 +0000 |
| commit | 6cbb108abc0159b0cc0502afe7261b6305f014a4 (patch) | |
| tree | caf04fe12e143389eaf783a5b6cbb758966eb40a /lib/libfetch | |
| parent | 965e9efdfaf4bc456fa575ca5f2d41df01a641e6 (diff) | |
Notes
Diffstat (limited to 'lib/libfetch')
| -rw-r--r-- | lib/libfetch/http.c | 64 |
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; |
