Bound FTP range transfers to requested size
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(libprozilla VERSION 1.2.0 LANGUAGES C)
|
||||
project(libprozilla VERSION 1.2.1 LANGUAGES C)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
||||
+24
-2
@@ -12,7 +12,9 @@ typedef struct {
|
||||
CURL *curl;
|
||||
int write_failed;
|
||||
int require_partial_response;
|
||||
int range_complete;
|
||||
size_t bytes_written;
|
||||
off_t expected_bytes;
|
||||
} curl_write_context;
|
||||
|
||||
static CURLcode configure_curl(CURL *curl, connection_t *connection)
|
||||
@@ -122,6 +124,20 @@ static size_t curl_write(void *data, size_t size, size_t count, void *opaque)
|
||||
if (size != 0 && count > SIZE_MAX / size)
|
||||
return 0;
|
||||
bytes = size * count;
|
||||
if (ctx->expected_bytes > 0)
|
||||
{
|
||||
off_t remaining = ctx->expected_bytes - (off_t) ctx->bytes_written;
|
||||
if (remaining <= 0)
|
||||
{
|
||||
ctx->range_complete = 1;
|
||||
return 0;
|
||||
}
|
||||
if ((uintmax_t) bytes > (uintmax_t) remaining)
|
||||
{
|
||||
bytes = (size_t) remaining;
|
||||
ctx->range_complete = 1;
|
||||
}
|
||||
}
|
||||
if (ctx->require_partial_response)
|
||||
{
|
||||
curl_easy_getinfo(ctx->curl, CURLINFO_RESPONSE_CODE, &response);
|
||||
@@ -139,6 +155,8 @@ static size_t curl_write(void *data, size_t size, size_t count, void *opaque)
|
||||
ctx->bytes_written += bytes;
|
||||
connection_calc_ratebps(ctx->connection);
|
||||
connection_throttle_bps(ctx->connection);
|
||||
if (ctx->range_complete)
|
||||
return 0;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@@ -146,7 +164,7 @@ static uerr_t curl_get_file(connection_t *connection)
|
||||
{
|
||||
CURL *curl = curl_easy_init();
|
||||
CURLcode result;
|
||||
curl_write_context ctx = { connection, curl, 0, 0, 0 };
|
||||
curl_write_context ctx = { connection, curl, 0, 0, 0, 0, 0 };
|
||||
char range[96];
|
||||
long response = 0;
|
||||
|
||||
@@ -161,6 +179,8 @@ static uerr_t curl_get_file(connection_t *connection)
|
||||
(intmax_t) connection->remote_startpos,
|
||||
(intmax_t) (connection->remote_endpos - 1));
|
||||
curl_easy_setopt(curl, CURLOPT_RANGE, range);
|
||||
ctx.expected_bytes =
|
||||
connection->remote_endpos - connection->remote_startpos;
|
||||
if (connection->u.proto == URLHTTP
|
||||
|| connection->u.proto == URLHTTPS)
|
||||
ctx.require_partial_response = 1;
|
||||
@@ -181,7 +201,9 @@ static uerr_t curl_get_file(connection_t *connection)
|
||||
&& (off_t) ctx.bytes_written
|
||||
!= connection->remote_endpos - connection->remote_startpos)
|
||||
return READERR;
|
||||
if (result == CURLE_OK && response < 400)
|
||||
if ((ctx.expected_bytes > 0
|
||||
&& (off_t) ctx.bytes_written == ctx.expected_bytes)
|
||||
|| ((result == CURLE_OK || ctx.range_complete) && response < 400))
|
||||
{
|
||||
connection_change_status(connection, COMPLETED);
|
||||
return HOK;
|
||||
|
||||
Reference in New Issue
Block a user