summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Petry <PVince81@yahoo.fr>2021-01-04 21:50:03 +0100
committerVincent Petry <PVince81@yahoo.fr>2021-01-04 21:50:03 +0100
commit216f62ea1468933f4a78f17885b27e37e1393d8c (patch)
tree16b83d625cb13de7c9c7425fbdae452363bf87ae /src
parentb7d0001390766127cb51b7e12b5765cfc04ed807 (diff)
Webdav href in response can be relative
Fixed Webdav base path stripping in cases where href is a relative path. Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
Diffstat (limited to 'src')
-rw-r--r--src/storage/plugins/CurlStorage.cxx33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx
index c986a8a49..298d70967 100644
--- a/src/storage/plugins/CurlStorage.cxx
+++ b/src/storage/plugins/CurlStorage.cxx
@@ -468,11 +468,19 @@ CurlStorage::GetInfo(std::string_view uri_utf8, [[maybe_unused]] bool follow)
gcc_pure
static std::string_view
-UriPathOrSlash(const char *uri) noexcept
+UriPathOrSlash(const char *uri, bool relative) noexcept
{
auto path = uri_get_path(uri);
if (path.data() == nullptr)
path = "/";
+ else if (relative) {
+ // search after first slash
+ path = path.substr(1);
+ auto slash = path.find('/');
+ if (slash != std::string_view::npos)
+ path = path.substr(slash);
+ }
+
return path;
}
@@ -481,13 +489,15 @@ UriPathOrSlash(const char *uri) noexcept
*/
class HttpListDirectoryOperation final : public PropfindOperation {
const std::string base_path;
+ const std::string base_path_relative;
MemoryStorageDirectoryReader::List entries;
public:
HttpListDirectoryOperation(CurlGlobal &curl, const char *uri)
:PropfindOperation(curl, uri, 1),
- base_path(CurlUnescape(GetEasy(), UriPathOrSlash(uri))) {}
+ base_path(CurlUnescape(GetEasy(), UriPathOrSlash(uri, false))),
+ base_path_relative(CurlUnescape(GetEasy(), UriPathOrSlash(uri, true))) {}
std::unique_ptr<StorageDirectoryReader> Perform() {
DeferStart();
@@ -506,6 +516,7 @@ private:
*/
gcc_pure
StringView HrefToEscapedName(const char *href) const noexcept {
+ StringView relative_path;
StringView path = uri_get_path(href);
if (path == nullptr)
return nullptr;
@@ -513,17 +524,23 @@ private:
/* kludge: ignoring case in this comparison to avoid
false negatives if the web server uses a different
case */
- path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
- if (path == nullptr || path.empty())
+ relative_path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
+ if (relative_path == nullptr || relative_path.empty()) {
+ // try relative base path
+ relative_path = StringAfterPrefixIgnoreCase(path, base_path_relative.c_str());
+ }
+
+ if (relative_path == nullptr || relative_path.empty()) {
return nullptr;
+ }
- const char *slash = path.Find('/');
+ const char *slash = relative_path.Find('/');
if (slash == nullptr)
/* regular file */
- return path;
- else if (slash == &path.back())
+ return relative_path;
+ else if (slash == &relative_path.back())
/* trailing slash: collection; strip the slash */
- return {path.data, slash};
+ return {relative_path.data, slash};
else
/* strange, better ignore it */
return nullptr;