tool_cb_hdr: allow etag and content-disposition for 3xx reply

- Parse etag and content-disposition headers for 3xx replies.

For example, a server may send a content-disposition filename header
with a redirect reply (3xx) but not with the final response (2xx).
Without this change curl would ignore the server's specified filename
and continue to use the filename extracted from the user-specified URL.

Prior to this change, 75d79a4 had limited etag and content-disposition
to 2xx replies only.

Tests-by: Daniel Stenberg

Reported-by: Morgan Willcock
Fixes https://github.com/curl/curl/issues/13302
Closes #13484
This commit is contained in:
Jay Satiro 2024-04-26 02:29:20 -04:00 committed by Daniel Stenberg
parent cb5c7039e8
commit 85efbb92b8
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 129 additions and 3 deletions

View File

@ -118,8 +118,9 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
long response = 0;
curl_easy_getinfo(per->curl, CURLINFO_RESPONSE_CODE, &response);
if(response/100 != 2)
/* only care about these headers in 2xx responses */
if((response/100 != 2) && (response/100 != 3))
/* only care about etag and content-disposition headers in 2xx and 3xx
responses */
;
/*
* Write etag to file when --etag-save option is given.

View File

@ -73,7 +73,7 @@ test426 test427 test428 test429 test430 test431 test432 test433 test434 \
test435 test436 test437 test438 test439 test440 test441 test442 test443 \
test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \
test462 test463 test467 test468 test469 test470 test471 test472 \
test462 test463 test467 test468 test469 test470 test471 test472 test473 \
\
test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \
@ -189,6 +189,7 @@ test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \
test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \
test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \
test1479 test1480 test1481 test1482 test1483 test1484 test1485 test1486 \
test1487 \
\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \

62
tests/data/test1487 Normal file
View File

@ -0,0 +1,62 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
-J
</keywords>
</info>
#
<reply>
<data nocheck="yes">
HTTP/1.1 301 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Length: 6
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
12345
</data>
</reply>
#
# Client-side
<client>
# this relies on the debug feature to allow us to set directory to store the
# -J output in
<features>
debug
</features>
<server>
http
</server>
<name>
HTTP GET with -J and Content-Disposition on 301
</name>
<setenv>
CURL_TESTDIR=%LOGDIR
</setenv>
<command option="no-output,no-include">
http://%HOSTIP:%HTTPPORT/%TESTNUMBER -J -O
</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: */*
</protocol>
<file name="%LOGDIR/name%TESTNUMBER">
12345
</file>
</verify>
</testcase>

62
tests/data/test473 Normal file
View File

@ -0,0 +1,62 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 301 funky chunky!
Server: fakeit/0.9 fakeitbad/1.0
Location: /redirected
Transfer-Encoding: chunked
Trailer: chunky-trailer
Connection: mooo
ETag: W/"asdf"
40
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
30
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
21;heresatest=moooo
cccccccccccccccccccccccccccccccc
0
chunky-trailer: header data
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<name>
Check if --etag-save saved correct etag to a file on 301
</name>
<command>
http://%HOSTIP:%HTTPPORT/%TESTNUMBER --etag-save %LOGDIR/etag%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: */*
</protocol>
<file name="%LOGDIR/etag%TESTNUMBER">
W/"asdf"
</file>
</verify>
</testcase>