file: support GETing directories again

After 957bc1881e686f9714c4e6a01bf33535091f0e21, we no longer compute an
expected_size for directories. This has the upshot that when we compare
even an empty Range with the available size, we fail.

This brings back the previous behaviour, which was to succeed, but with
empty content. This also removes the "Accept-ranges: bytes" header,
which is nonsensical on directories.

Adds test 3016
Fixes #6845
Closes #6846
This commit is contained in:
Luke Granger-Brown 2021-04-03 19:12:48 +00:00 committed by Daniel Stenberg
parent f6bbc3407a
commit 6d930d7306
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 53 additions and 13 deletions

View File

@ -417,12 +417,12 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
}
result = Curl_client_write(data, CLIENTWRITE_HEADER,
(char *)"Accept-ranges: bytes\r\n", 0);
if(result)
return result;
result = Curl_client_write(data, CLIENTWRITE_HEADER,
(char *)"Accept-ranges: bytes\r\n", 0);
if(result != CURLE_OK)
return result;
}
filetime = (time_t)statbuf.st_mtime;
result = Curl_gmtime(filetime, &buffer);
@ -464,18 +464,23 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
data->state.resume_from += (curl_off_t)statbuf.st_size;
}
if(data->state.resume_from <= expected_size)
expected_size -= data->state.resume_from;
else {
failf(data, "failed to resume file:// transfer");
return CURLE_BAD_DOWNLOAD_RESUME;
if(data->state.resume_from > 0) {
/* We check explicitly if we have a start offset, because
* expected_size may be -1 if we don't know how large the file is,
* in which case we should not adjust it. */
if(data->state.resume_from <= expected_size)
expected_size -= data->state.resume_from;
else {
failf(data, "failed to resume file:// transfer");
return CURLE_BAD_DOWNLOAD_RESUME;
}
}
/* A high water mark has been specified so we obey... */
if(data->req.maxdownload > 0)
expected_size = data->req.maxdownload;
if(!fstated || (expected_size == 0))
if(!fstated || (expected_size <= 0))
size_known = FALSE;
else
size_known = TRUE;
@ -484,7 +489,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
this is both more efficient than the former call to download() and
it avoids problems with select() and recv() on file descriptors
in Winsock */
if(fstated)
if(size_known)
Curl_pgrsSetDownloadSize(data, expected_size);
if(data->state.resume_from) {

View File

@ -229,4 +229,5 @@ test2080 test2081 \
test2100 \
\
test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \
test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015
test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015 \
test3016

34
tests/data/test3016 Normal file
View File

@ -0,0 +1,34 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
FILE
</keywords>
</info>
#
# Client-side
<client>
<server>
file
</server>
<name>
GET a directory using file://
</name>
<!-- doesn't work on win32, see #6379 -->
<features>
!win32
</features>
<command>
file://%PWD/
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<errorcode>
0
</errorcode>
</verify>