Skip to content

Commit

Permalink
Fix HTTP request-ranges to be zero-based
Browse files Browse the repository at this point in the history
This changes the interpretation of http_t.firstbyte, with
-1 meaning the server doesn't support partial requests.

Fixes: axel-download-accelerator#206

Signed-off-by: Ismael Luceno <ismael@iodev.co.uk>
  • Loading branch information
ismaell committed May 14, 2019
1 parent 66f278f commit 06fa69f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 36 deletions.
7 changes: 3 additions & 4 deletions src/axel.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ axel_do(axel_t *axel)
if (size == 0) {
if (axel->conf->verbose) {
/* Only abnormal behaviour if: */
if (axel->conn[i].currentbyte <
if (axel->conn[i].currentbyte <=
axel->conn[i].lastbyte &&
axel->size != LLONG_MAX) {
axel_message(axel,
Expand All @@ -547,8 +547,7 @@ axel_do(axel_t *axel)
}

/* remaining == Bytes to go */
remaining =
axel->conn[i].lastbyte - axel->conn[i].currentbyte + 1;
remaining = axel->conn[i].lastbyte - axel->conn[i].currentbyte;
if (remaining < size) {
if (axel->conf->verbose) {
axel_message(axel, _("Connection %i finished"),
Expand Down Expand Up @@ -587,7 +586,7 @@ axel_do(axel_t *axel)
continue;

if (!axel->conn[i].enabled &&
axel->conn[i].currentbyte < axel->conn[i].lastbyte) {
axel->conn[i].currentbyte <= axel->conn[i].lastbyte) {
if (!axel->conn[i].state) {
// Wait for termination of this thread
pthread_join(*(axel->conn[i].setup_thread),
Expand Down
59 changes: 28 additions & 31 deletions src/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ conn_setup(conn_t *conn)
int i;

snprintf(s, sizeof(s), "%s%s", conn->dir, conn->file);
conn->http->firstbyte = conn->currentbyte;
conn->http->firstbyte =
conn->supported ? conn->currentbyte : -1;
conn->http->lastbyte = conn->lastbyte;
http_get(conn->http, s);
for (i = 0; i < conn->conf->add_header_count; i++)
Expand Down Expand Up @@ -365,7 +366,8 @@ conn_info(conn_t *conn)
do {
const char *t;

conn->currentbyte = 1;
conn->supported = true;
conn->currentbyte = 0;
if (!conn_setup(conn))
return 0;
conn_exec(conn);
Expand Down Expand Up @@ -410,36 +412,31 @@ conn_info(conn_t *conn)
return 0;
}

conn->size = http_size(conn->http);
i = http_size_from_range(conn->http);
if (i > 0 && conn->size + 1 != i) {
/* This means that the server has a bug. This version currently
uses the larger of the reported sizes, but it would be an
alternative to set supported = false. */
conn->supported = true;
conn->size = max(i, conn->size + 1);
} else if (conn->http->status == 206 && conn->size >= 0) {
/* 206: range request supported */
conn->supported = true;
conn->size++;
} else if (conn->http->status == 200
|| conn->http->status == 206) {
/* something is not supported - fallback */
conn->supported = false;
conn->size = http_size_from_range(conn->http);
/* We assume partial requests are supported if a Content-Range
* header is present.
*/
conn->supported = conn->http->status == 206 || conn->size > 0;

/* If Content-Length and Content-Range disagree, it's a server
* bug; we take the larger and hope for the best.
*/
conn->size = max(conn->size, http_size(conn->http));

if (conn->size <= 0) {
/* Sanity check */
switch (conn->http->status) {
case 200:
case 206:
case 416:
break;
default: /* unexpected */
return 0;
}

/* if we have an invalid size, set it to the max so that
* the transfer will finish when the server closes the
* connection. Otherwise keep the reported size. */
if (conn->size <= 0)
conn->size = LLONG_MAX;
} else {
char *t = strchr(conn->message, '\n');
if (t == NULL)
sprintf(conn->message,
_("Unknown HTTP error.\n"));
else
*t = 0;
return 0;
/* So we got an invalid or no size, fall back */
conn->supported = false;
conn->size = LLONG_MAX;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ http_get(http_t *conn, char *lurl)
http_addheader(conn, "Proxy-Authorization: Basic %s",
conn->proxy_auth);
http_addheader(conn, "Accept: */*");
if (conn->firstbyte) {
if (conn->firstbyte >= 0) {
if (conn->lastbyte)
http_addheader(conn, "Range: bytes=%lld-%lld",
conn->firstbyte, conn->lastbyte);
Expand Down

0 comments on commit 06fa69f

Please sign in to comment.