Skip to content

Commit 0f889ce

Browse files
committed
/vsicurl/: fix a redirect to a URL ending with a slash followed by a 403
1 parent 5b39029 commit 0f889ce

File tree

2 files changed

+50
-21
lines changed

2 files changed

+50
-21
lines changed

autotest/gcore/vsicurl.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,3 +1742,27 @@ def test_VSIFOpenExL_CACHE_NO(server):
17421742

17431743
with gdal.VSIFile(filename, "rb", False, {"CACHE": "NO"}) as f:
17441744
assert f.read() == b"1234"
1745+
1746+
1747+
###############################################################################
1748+
# Test redirection to a URL ending with a slash, followed by a 403
1749+
1750+
1751+
def test_vsicurl_test_redirect_301_to_url_ending_slash_and_then_403(server):
1752+
1753+
gdal.VSICurlClearCache()
1754+
1755+
handler = webserver.SequentialHandler()
1756+
handler.add(
1757+
"HEAD",
1758+
"/test_redirect",
1759+
301,
1760+
{"Location": "http://localhost:%d/test_redirect/" % server.port},
1761+
)
1762+
handler.add("HEAD", "/test_redirect/", 403)
1763+
1764+
with webserver.install_http_handler(handler), gdal.quiet_errors():
1765+
assert (
1766+
gdal.VSIStatL("/vsicurl/http://localhost:%d/test_redirect" % server.port)
1767+
is None
1768+
)

port/cpl_vsil_curl.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,31 +1363,35 @@ vsi_l_offset VSICurlHandle::GetFileSizeOrHeaders(bool bSetError,
13631363
}
13641364
}
13651365

1366-
curl_off_t nSizeTmp = 0;
1367-
const CURLcode code = curl_easy_getinfo(
1368-
hCurlHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &nSizeTmp);
1369-
CPL_IGNORE_RET_VAL(dfSize);
1370-
dfSize = static_cast<double>(nSizeTmp);
1371-
if (code == 0)
1366+
if (response_code < 400)
13721367
{
1373-
oFileProp.eExists = EXIST_YES;
1374-
if (dfSize < 0)
1368+
curl_off_t nSizeTmp = 0;
1369+
const CURLcode code = curl_easy_getinfo(
1370+
hCurlHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &nSizeTmp);
1371+
CPL_IGNORE_RET_VAL(dfSize);
1372+
dfSize = static_cast<double>(nSizeTmp);
1373+
if (code == 0)
13751374
{
1376-
if (osVerb == "HEAD" && !bRetryWithGet && response_code == 200)
1375+
oFileProp.eExists = EXIST_YES;
1376+
if (dfSize < 0)
13771377
{
1378-
CPLDebug(
1379-
poFS->GetDebugKey(),
1380-
"HEAD did not provide file size. Retrying with GET");
1381-
bRetryWithGet = true;
1382-
CPLFree(sWriteFuncData.pBuffer);
1383-
CPLFree(sWriteFuncHeaderData.pBuffer);
1384-
curl_easy_cleanup(hCurlHandle);
1385-
goto retry;
1378+
if (osVerb == "HEAD" && !bRetryWithGet &&
1379+
response_code == 200)
1380+
{
1381+
CPLDebug(poFS->GetDebugKey(),
1382+
"HEAD did not provide file size. Retrying "
1383+
"with GET");
1384+
bRetryWithGet = true;
1385+
CPLFree(sWriteFuncData.pBuffer);
1386+
CPLFree(sWriteFuncHeaderData.pBuffer);
1387+
curl_easy_cleanup(hCurlHandle);
1388+
goto retry;
1389+
}
1390+
oFileProp.fileSize = 0;
13861391
}
1387-
oFileProp.fileSize = 0;
1392+
else
1393+
oFileProp.fileSize = static_cast<GUIntBig>(dfSize);
13881394
}
1389-
else
1390-
oFileProp.fileSize = static_cast<GUIntBig>(dfSize);
13911395
}
13921396

13931397
if (sWriteFuncHeaderData.pBuffer != nullptr &&
@@ -1605,7 +1609,8 @@ vsi_l_offset VSICurlHandle::GetFileSizeOrHeaders(bool bSetError,
16051609
// directory, curl will retry with an URL with slash added.
16061610
if (!osEffectiveURL.empty() &&
16071611
strncmp(osURL.c_str(), osEffectiveURL.c_str(), osURL.size()) == 0 &&
1608-
osEffectiveURL[osURL.size()] == '/')
1612+
osEffectiveURL[osURL.size()] == '/' &&
1613+
oFileProp.eExists != EXIST_NO)
16091614
{
16101615
oFileProp.eExists = EXIST_YES;
16111616
oFileProp.fileSize = 0;

0 commit comments

Comments
 (0)