tool_operate: keep failed partial download for retry auto-resume

- Keep data from a failed download instead of discarding it on retry in
  some limited cases when we know it's ok (currently only HTTP 200/206).

Prior to this change on failed transfer the tool truncated any outfile
data written before retrying the transfer. This change adds an exception
for HTTP downloads when the user requested auto-resume, because in that
case we can keep the outfile data and resume from the new position.

Reported-by: tkzv@users.noreply.github.com

Fixes https://github.com/curl/curl/issues/18035
Closes https://github.com/curl/curl/pull/18665
This commit is contained in:
Jay Satiro 2024-10-18 14:12:31 -04:00
parent d1d5855689
commit e7247d8697
3 changed files with 200 additions and 3 deletions

View file

@ -275,7 +275,7 @@ test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 \
test3008 test3009 test3010 test3011 test3012 test3013 test3014 test3015 \
test3016 test3017 test3018 test3019 test3020 test3021 test3022 test3023 \
test3024 test3025 test3026 test3027 test3028 test3029 test3030 test3031 \
test3032 test3033 test3034 \
test3032 test3033 test3034 test3035 \
\
test3100 test3101 test3102 test3103 test3104 test3105 \
\

127
tests/data/test3035 Normal file
View file

@ -0,0 +1,127 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
Content-Range
Resume
retry
</keywords>
</info>
# Server-side
<reply>
#
# the first chunk
#
<data nocheck="yes" nonewline="yes">
HTTP/1.1 200 OK swsbounce swsclose
Accept-Ranges: bytes
Content-Type: text/html
Content-Length: 26
abcde
</data>
#
# the second chunk
#
<data1 nocheck="yes" nonewline="yes">
HTTP/1.1 206 Partial Content swsbounce swsclose
Content-Type: text/html
Content-Length: 21
Content-Range: bytes 5-25/26
fghijk
</data1>
#
# some nonsense that curl should ignore as unresumable
#
<data2 nocheck="yes">
HTTP/1.1 404 Not Found swsbounce
Content-Type: text/html
Content-Length: 5
body
</data2>
#
# some more nonsense that curl should ignore as unresumable
#
<data3 nocheck="yes">
HTTP/1.1 200 OK swsbounce
Accept-Ranges: bytes
Content-Type: text/html
Content-Length: 30
XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</data3>
#
# the third chunk
#
<data4 nocheck="yes" nonewline="yes">
HTTP/1.1 206 Partial Content swsbounce swsclose
Content-Type: text/html
Content-Length: 15
Content-Range: bytes 11-25/26
lmnopqrstuvwxyz
</data4>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
HTTP retry failed download with keep data and auto-resume
</name>
<command option="no-output,no-include">
--continue-at - --retry 4 --retry-delay 1 --retry-all-errors -o %LOGDIR/outfile%TESTNUMBER http://%HOSTIP:%HTTPPORT/%TESTNUMBER
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=5-
User-Agent: curl/%VERSION
Accept: */*
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=11-
User-Agent: curl/%VERSION
Accept: */*
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=11-
User-Agent: curl/%VERSION
Accept: */*
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Range: bytes=11-
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="%LOGDIR/outfile%TESTNUMBER" nonewline="yes">
abcdefghijklmnopqrstuvwxyz
</file1>
</verify>
</testcase>