summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Granger-Brown <git@lukegb.com>2021-04-03 19:12:48 +0000
committerDaniel Stenberg <daniel@haxx.se>2021-04-05 12:22:07 +0200
commit6d930d730600771f15ab048a123f253ce4751786 (patch)
treefe9912900d98e455f453a3354731a89bf52d757e
parentf6bbc3407ad6c62e44c0b87da84c5a8ffa5560ee (diff)
downloadcurl-6d930d730600771f15ab048a123f253ce4751786.tar.gz
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
-rw-r--r--lib/file.c29
-rw-r--r--tests/data/Makefile.inc3
-rw-r--r--tests/data/test301634
3 files changed, 53 insertions, 13 deletions
diff --git a/lib/file.c b/lib/file.c
index dd8a1fd12..1d174e519 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -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) {
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index ea52683d2..6ae2a249b 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -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
diff --git a/tests/data/test3016 b/tests/data/test3016
new file mode 100644
index 000000000..b64507476
--- /dev/null
+++ b/tests/data/test3016
@@ -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>