Merge pull request #11469 from rouault/fix_11467
CPLGetPath()/CPLGetDirname(): make them work with /vsicurl? and URL encoded
This commit is contained in:
commit
0ed4def329
|
@ -1059,6 +1059,12 @@ TEST_F(test_cpl, CPLGetPath)
|
|||
EXPECT_STREQ(CPLGetPath("/foo/bar"), "/foo");
|
||||
EXPECT_STREQ(CPLGetPath("/vsicurl/http://example.com/foo/bar?suffix"),
|
||||
"/vsicurl/http://example.com/foo?suffix");
|
||||
EXPECT_STREQ(
|
||||
CPLGetPath(
|
||||
"/vsicurl?foo=bar&url=https%3A%2F%2Fraw.githubusercontent.com%"
|
||||
"2FOSGeo%2Fgdal%2Fmaster%2Fautotest%2Fogr%2Fdata%2Fpoly.shp"),
|
||||
"/vsicurl?foo=bar&url=https%3A%2F%2Fraw.githubusercontent.com%2FOSGeo%"
|
||||
"2Fgdal%2Fmaster%2Fautotest%2Fogr%2Fdata");
|
||||
}
|
||||
|
||||
TEST_F(test_cpl, CPLGetDirname)
|
||||
|
@ -1067,6 +1073,12 @@ TEST_F(test_cpl, CPLGetDirname)
|
|||
EXPECT_STREQ(CPLGetDirname("/foo/bar"), "/foo");
|
||||
EXPECT_STREQ(CPLGetDirname("/vsicurl/http://example.com/foo/bar?suffix"),
|
||||
"/vsicurl/http://example.com/foo?suffix");
|
||||
EXPECT_STREQ(
|
||||
CPLGetDirname(
|
||||
"/vsicurl?foo=bar&url=https%3A%2F%2Fraw.githubusercontent.com%"
|
||||
"2FOSGeo%2Fgdal%2Fmaster%2Fautotest%2Fogr%2Fdata%2Fpoly.shp"),
|
||||
"/vsicurl?foo=bar&url=https%3A%2F%2Fraw.githubusercontent.com%2FOSGeo%"
|
||||
"2Fgdal%2Fmaster%2Fautotest%2Fogr%2Fdata");
|
||||
}
|
||||
|
||||
TEST_F(test_cpl, VSIGetDiskFreeSpace)
|
||||
|
|
|
@ -1745,6 +1745,35 @@ def test_ogr_shape_44():
|
|||
assert f is not None, "did not get expected feature"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test /vsicurl?url=
|
||||
|
||||
|
||||
@pytest.mark.require_curl()
|
||||
def test_ogr_shape_vsicurl_url():
|
||||
|
||||
conn = gdaltest.gdalurlopen(
|
||||
"https://raw.githubusercontent.com/OSGeo/gdal/release/3.10/autotest/ogr/data/poly.shp"
|
||||
)
|
||||
if conn is None:
|
||||
pytest.skip("cannot open URL")
|
||||
conn.close()
|
||||
|
||||
ds = ogr.Open(
|
||||
"/vsicurl?url=https%3A%2F%2Fraw.githubusercontent.com%2FOSGeo%2Fgdal%2Frelease%2F3.10%2Fautotest%2Fogr%2Fdata%2Fpoly.shp"
|
||||
)
|
||||
assert ds is not None
|
||||
|
||||
lyr = ds.GetLayer(0)
|
||||
|
||||
srs = lyr.GetSpatialRef()
|
||||
wkt = srs.ExportToWkt()
|
||||
assert wkt.find("OSGB") != -1, "did not get expected SRS"
|
||||
|
||||
f = lyr.GetNextFeature()
|
||||
assert f is not None, "did not get expected feature"
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Test ignored fields works ok on a shapefile.
|
||||
|
||||
|
|
|
@ -128,6 +128,10 @@ static int CPLFindFilenameStart(const char *pszFilename, size_t nStart = 0)
|
|||
const char *CPLGetPath(const char *pszFilename)
|
||||
|
||||
{
|
||||
char *pszStaticResult = CPLGetStaticResult();
|
||||
if (pszStaticResult == nullptr)
|
||||
return CPLStaticBufferTooSmall(pszStaticResult);
|
||||
|
||||
size_t nSuffixPos = 0;
|
||||
if (STARTS_WITH(pszFilename, "/vsicurl/http"))
|
||||
{
|
||||
|
@ -135,11 +139,41 @@ const char *CPLGetPath(const char *pszFilename)
|
|||
if (pszQuestionMark)
|
||||
nSuffixPos = static_cast<size_t>(pszQuestionMark - pszFilename);
|
||||
}
|
||||
else if (STARTS_WITH(pszFilename, "/vsicurl?") &&
|
||||
strstr(pszFilename, "url="))
|
||||
{
|
||||
std::string osRet;
|
||||
const CPLStringList aosTokens(
|
||||
CSLTokenizeString2(pszFilename + strlen("/vsicurl?"), "&", 0));
|
||||
for (int i = 0; i < aosTokens.size(); i++)
|
||||
{
|
||||
if (osRet.empty())
|
||||
osRet = "/vsicurl?";
|
||||
else
|
||||
osRet += '&';
|
||||
if (STARTS_WITH(aosTokens[i], "url=") &&
|
||||
!STARTS_WITH(aosTokens[i], "url=/vsicurl"))
|
||||
{
|
||||
char *pszUnescaped =
|
||||
CPLUnescapeString(aosTokens[i], nullptr, CPLES_URL);
|
||||
char *pszPath = CPLEscapeString(
|
||||
CPLGetPath(pszUnescaped + strlen("url=")), -1, CPLES_URL);
|
||||
osRet += "url=";
|
||||
osRet += pszPath;
|
||||
CPLFree(pszPath);
|
||||
CPLFree(pszUnescaped);
|
||||
}
|
||||
else
|
||||
{
|
||||
osRet += aosTokens[i];
|
||||
}
|
||||
}
|
||||
CPLStrlcpy(pszStaticResult, osRet.c_str(), CPL_PATH_BUF_SIZE);
|
||||
return pszStaticResult;
|
||||
}
|
||||
|
||||
const int iFileStart = CPLFindFilenameStart(pszFilename, nSuffixPos);
|
||||
char *pszStaticResult = CPLGetStaticResult();
|
||||
|
||||
if (pszStaticResult == nullptr || iFileStart >= CPL_PATH_BUF_SIZE)
|
||||
if (iFileStart >= CPL_PATH_BUF_SIZE)
|
||||
return CPLStaticBufferTooSmall(pszStaticResult);
|
||||
|
||||
CPLAssert(!(pszFilename >= pszStaticResult &&
|
||||
|
@ -197,6 +231,10 @@ const char *CPLGetPath(const char *pszFilename)
|
|||
const char *CPLGetDirname(const char *pszFilename)
|
||||
|
||||
{
|
||||
char *pszStaticResult = CPLGetStaticResult();
|
||||
if (pszStaticResult == nullptr)
|
||||
return CPLStaticBufferTooSmall(pszStaticResult);
|
||||
|
||||
size_t nSuffixPos = 0;
|
||||
if (STARTS_WITH(pszFilename, "/vsicurl/http"))
|
||||
{
|
||||
|
@ -204,11 +242,42 @@ const char *CPLGetDirname(const char *pszFilename)
|
|||
if (pszQuestionMark)
|
||||
nSuffixPos = static_cast<size_t>(pszQuestionMark - pszFilename);
|
||||
}
|
||||
else if (STARTS_WITH(pszFilename, "/vsicurl?") &&
|
||||
strstr(pszFilename, "url="))
|
||||
{
|
||||
std::string osRet;
|
||||
const CPLStringList aosTokens(
|
||||
CSLTokenizeString2(pszFilename + strlen("/vsicurl?"), "&", 0));
|
||||
for (int i = 0; i < aosTokens.size(); i++)
|
||||
{
|
||||
if (osRet.empty())
|
||||
osRet = "/vsicurl?";
|
||||
else
|
||||
osRet += '&';
|
||||
if (STARTS_WITH(aosTokens[i], "url=") &&
|
||||
!STARTS_WITH(aosTokens[i], "url=/vsicurl"))
|
||||
{
|
||||
char *pszUnescaped =
|
||||
CPLUnescapeString(aosTokens[i], nullptr, CPLES_URL);
|
||||
char *pszPath = CPLEscapeString(
|
||||
CPLGetDirname(pszUnescaped + strlen("url=")), -1,
|
||||
CPLES_URL);
|
||||
osRet += "url=";
|
||||
osRet += pszPath;
|
||||
CPLFree(pszPath);
|
||||
CPLFree(pszUnescaped);
|
||||
}
|
||||
else
|
||||
{
|
||||
osRet += aosTokens[i];
|
||||
}
|
||||
}
|
||||
CPLStrlcpy(pszStaticResult, osRet.c_str(), CPL_PATH_BUF_SIZE);
|
||||
return pszStaticResult;
|
||||
}
|
||||
|
||||
const int iFileStart = CPLFindFilenameStart(pszFilename, nSuffixPos);
|
||||
char *pszStaticResult = CPLGetStaticResult();
|
||||
|
||||
if (pszStaticResult == nullptr || iFileStart >= CPL_PATH_BUF_SIZE)
|
||||
if (iFileStart >= CPL_PATH_BUF_SIZE)
|
||||
return CPLStaticBufferTooSmall(pszStaticResult);
|
||||
|
||||
CPLAssert(!(pszFilename >= pszStaticResult &&
|
||||
|
|
Loading…
Reference in New Issue