release v0.21.16
-----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEA5IzWngIOJSkMBxDI26KWMbbRRIFAl2m6cwQHG1heEBtdXNp Y3BkLm9yZwAKCRAjbopYxttFEuMlD/9W6UTA9WfbeB2k8F2gFvy30w3jarsIdANG iRl2qW8a/MSp6zNj5t3rIH/JTOPEVXgB7c844gIC2VHkKAu4M3kV2sqa7cDEcq6o tFH5npemuCFbpkkAqXHpgFindWGMOqZy01PCN8m70y9IbfmI0Q25jngKeeuzgZ9O 4DHw9IniWNamAi9H3MdGt6BpyuQ+EJ+FOfuJdsJkLgfK15qMn/3LwNoUyCxjyK/K brdQO0qpBg7dLZoGb6ER7qkyV1Cp+z/Mqeeocn4iQf3RuepIKzhZFMB1MY9FS7O1 YAA89Lpk9mvLqx1/LkArrPEOv7k5Ia5KSmxZJ5dsrdXm/TKVM1k0MxZuE7LoXLXp wbdhXFoyhuL6lwLkw20wj1zqcTGMAYIp6t48YbDlVy59f/9OVROr++pCQsY+3L2t JPY90z6hf6yDF5yZCucSt7gin/WXRdeQLTgAxd8EqGqFgIRrW0GZhssg+7O1iGCq aSAVlxfzhVFxz7eyo4u3Dq/+d6gh3NRzV6exUYMxp3WHu7eweemlnKyxPxQ1lvSF 5EkZXC56wQp0JIcIRYLEXkJN8lmIy/i0xHaOLDB7cJN23CC5Z68Up6peCzvVPp+E PIzOtT+4/FnQ6euu6KLHeiDyTWxdmGSrSP1W6cc/FpyLU86ZV/5tLg0bEaNxb9Sl lYfRth0D/A== =9Cv+ -----END PGP SIGNATURE----- Merge tag 'v0.21.16' release v0.21.16
This commit is contained in:
commit
e1867a99e9
11
NEWS
11
NEWS
|
@ -32,6 +32,17 @@ ver 0.22 (not yet released)
|
||||||
* switch to C++17
|
* switch to C++17
|
||||||
- GCC 7 or clang 4 (or newer) recommended
|
- GCC 7 or clang 4 (or newer) recommended
|
||||||
|
|
||||||
|
ver 0.21.16 (2019/10/16)
|
||||||
|
* queue
|
||||||
|
- fix relative destination offset when moving a range
|
||||||
|
* storage
|
||||||
|
- curl: request the "resourcetype" property to fix database update
|
||||||
|
- curl: URL-encode more paths
|
||||||
|
- curl: follow redirects for collections without trailing slash
|
||||||
|
* update
|
||||||
|
- fix crash when music_directory is not a directory
|
||||||
|
* fix build with iconv() instead of ICU
|
||||||
|
|
||||||
ver 0.21.15 (2019/09/25)
|
ver 0.21.15 (2019/09/25)
|
||||||
* decoder
|
* decoder
|
||||||
- dsdiff, dsf: fix displayed bit rate
|
- dsdiff, dsf: fix displayed bit rate
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.musicpd"
|
package="org.musicpd"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="38"
|
android:versionCode="39"
|
||||||
android:versionName="0.21.15">
|
android:versionName="0.21.16">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
|
||||||
|
|
||||||
|
|
|
@ -475,6 +475,12 @@ UpdateWalk::Walk(Directory &root, const char *path, bool discard) noexcept
|
||||||
if (!GetInfo(storage, "", info))
|
if (!GetInfo(storage, "", info))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!info.IsDirectory()) {
|
||||||
|
FormatError(update_domain, "Not a directory: %s",
|
||||||
|
storage.MapUTF8("").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ExcludeList exclude_list;
|
ExcludeList exclude_list;
|
||||||
|
|
||||||
UpdateDirectory(root, exclude_list, info);
|
UpdateDirectory(root, exclude_list, info);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#ifndef CURL_EASY_HXX
|
#ifndef CURL_EASY_HXX
|
||||||
#define CURL_EASY_HXX
|
#define CURL_EASY_HXX
|
||||||
|
|
||||||
|
#include "String.hxx"
|
||||||
#include "util/Compiler.h"
|
#include "util/Compiler.h"
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
@ -208,8 +209,8 @@ public:
|
||||||
return ::curl_easy_pause(handle, CURLPAUSE_CONT) == CURLE_OK;
|
return ::curl_easy_pause(handle, CURLPAUSE_CONT) == CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Escape(const char *string, int length=0) const noexcept {
|
CurlString Escape(const char *string, int length=0) const noexcept {
|
||||||
return curl_easy_escape(handle, string, length);
|
return CurlString(curl_easy_escape(handle, string, length));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Escape.hxx"
|
||||||
|
#include "Easy.hxx"
|
||||||
|
#include "String.hxx"
|
||||||
|
#include "util/IterableSplitString.hxx"
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlEscapeUriPath(CURL *curl, StringView src) noexcept
|
||||||
|
{
|
||||||
|
std::string dest;
|
||||||
|
|
||||||
|
for (const auto i : IterableSplitString(src, '/')) {
|
||||||
|
CurlString escaped(curl_easy_escape(curl, i.data, i.size));
|
||||||
|
if (!dest.empty())
|
||||||
|
dest.push_back('/');
|
||||||
|
dest += escaped.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlEscapeUriPath(StringView src) noexcept
|
||||||
|
{
|
||||||
|
CurlEasy easy;
|
||||||
|
return CurlEscapeUriPath(easy.Get(), src);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlUnescape(CURL *curl, StringView src) noexcept
|
||||||
|
{
|
||||||
|
int outlength;
|
||||||
|
CurlString tmp(curl_easy_unescape(curl, src.data, src.size,
|
||||||
|
&outlength));
|
||||||
|
return std::string(tmp.c_str(), outlength);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlUnescape(StringView src) noexcept
|
||||||
|
{
|
||||||
|
CurlEasy easy;
|
||||||
|
return CurlUnescape(easy.Get(), src);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CURL_ESCAPE_HXX
|
||||||
|
#define CURL_ESCAPE_HXX
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct StringView;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlEscapeUriPath(CURL *curl, StringView src) noexcept;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlEscapeUriPath(StringView src) noexcept;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlUnescape(CURL *curl, StringView src) noexcept;
|
||||||
|
|
||||||
|
std::string
|
||||||
|
CurlUnescape(StringView src) noexcept;
|
||||||
|
|
||||||
|
#endif
|
|
@ -28,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Form.hxx"
|
#include "Form.hxx"
|
||||||
|
#include "String.hxx"
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EncodeForm(CURL *curl,
|
EncodeForm(CURL *curl,
|
||||||
|
@ -43,12 +44,10 @@ EncodeForm(CURL *curl,
|
||||||
result.push_back('=');
|
result.push_back('=');
|
||||||
|
|
||||||
if (!i.second.empty()) {
|
if (!i.second.empty()) {
|
||||||
char *value = curl_easy_escape(curl, i.second.data(),
|
CurlString value(curl_easy_escape(curl, i.second.data(),
|
||||||
i.second.length());
|
i.second.length()));
|
||||||
if (value != nullptr) {
|
if (value)
|
||||||
result.append(value);
|
result.append(value);
|
||||||
curl_free(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Max Kellermann <max.kellermann@gmail.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CURL_STRING_HXX
|
||||||
|
#define CURL_STRING_HXX
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OO wrapper for an allocated string to be freed with curl_free().
|
||||||
|
*/
|
||||||
|
class CurlString {
|
||||||
|
char *p = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CurlString() noexcept = default;
|
||||||
|
CurlString(std::nullptr_t) noexcept {}
|
||||||
|
|
||||||
|
explicit CurlString(char *_p) noexcept
|
||||||
|
:p(_p) {}
|
||||||
|
|
||||||
|
CurlString(CurlString &&src) noexcept
|
||||||
|
:p(std::exchange(src.p, nullptr)) {}
|
||||||
|
|
||||||
|
~CurlString() noexcept {
|
||||||
|
if (p != nullptr)
|
||||||
|
curl_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurlString &operator=(CurlString &&src) noexcept {
|
||||||
|
using std::swap;
|
||||||
|
swap(p, src.p);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const noexcept {
|
||||||
|
return p != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const char *() const noexcept {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *c_str() const noexcept {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -11,6 +11,7 @@ curl = static_library(
|
||||||
'Init.cxx',
|
'Init.cxx',
|
||||||
'Global.cxx',
|
'Global.cxx',
|
||||||
'Request.cxx',
|
'Request.cxx',
|
||||||
|
'Escape.cxx',
|
||||||
'Form.cxx',
|
'Form.cxx',
|
||||||
include_directories: inc,
|
include_directories: inc,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
|
|
@ -20,7 +20,7 @@ if icu_dep.found()
|
||||||
elif not get_option('iconv').disabled()
|
elif not get_option('iconv').disabled()
|
||||||
have_iconv = compiler.has_function('iconv')
|
have_iconv = compiler.has_function('iconv')
|
||||||
conf.set('HAVE_ICONV', have_iconv)
|
conf.set('HAVE_ICONV', have_iconv)
|
||||||
if get_option('iconv').enabled()
|
if not have_iconv and get_option('iconv').enabled()
|
||||||
error('iconv() not available')
|
error('iconv() not available')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -352,7 +352,7 @@ playlist::MoveRange(PlayerControl &pc,
|
||||||
return;
|
return;
|
||||||
to = (currentSong + abs(to)) % GetLength();
|
to = (currentSong + abs(to)) % GetLength();
|
||||||
if (start < (unsigned)to)
|
if (start < (unsigned)to)
|
||||||
to--;
|
to -= end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.MoveRange(start, end, to);
|
queue.MoveRange(start, end, to);
|
||||||
|
|
|
@ -25,8 +25,10 @@
|
||||||
#include "lib/curl/Init.hxx"
|
#include "lib/curl/Init.hxx"
|
||||||
#include "lib/curl/Global.hxx"
|
#include "lib/curl/Global.hxx"
|
||||||
#include "lib/curl/Slist.hxx"
|
#include "lib/curl/Slist.hxx"
|
||||||
|
#include "lib/curl/String.hxx"
|
||||||
#include "lib/curl/Request.hxx"
|
#include "lib/curl/Request.hxx"
|
||||||
#include "lib/curl/Handler.hxx"
|
#include "lib/curl/Handler.hxx"
|
||||||
|
#include "lib/curl/Escape.hxx"
|
||||||
#include "lib/expat/ExpatParser.hxx"
|
#include "lib/expat/ExpatParser.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
#include "event/DeferEvent.hxx"
|
#include "event/DeferEvent.hxx"
|
||||||
|
@ -34,7 +36,6 @@
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
#include "time/Parser.hxx"
|
#include "time/Parser.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/IterableSplitString.hxx"
|
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/StringFormat.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
|
@ -74,26 +75,15 @@ CurlStorage::MapUTF8(const char *uri_utf8) const noexcept
|
||||||
if (StringIsEmpty(uri_utf8))
|
if (StringIsEmpty(uri_utf8))
|
||||||
return base;
|
return base;
|
||||||
|
|
||||||
CurlEasy easy;
|
std::string path_esc = CurlEscapeUriPath(uri_utf8);
|
||||||
std::string path_esc;
|
|
||||||
|
|
||||||
for (auto elt: IterableSplitString(uri_utf8, '/')) {
|
|
||||||
char *elt_esc = easy.Escape(elt.data, elt.size);
|
|
||||||
if (!path_esc.empty())
|
|
||||||
path_esc.push_back('/');
|
|
||||||
path_esc += elt_esc;
|
|
||||||
curl_free(elt_esc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PathTraitsUTF8::Build(base.c_str(), path_esc.c_str());
|
return PathTraitsUTF8::Build(base.c_str(), path_esc.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
CurlStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
|
CurlStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
|
||||||
{
|
{
|
||||||
// TODO: escape/unescape?
|
return PathTraitsUTF8::Relative(base.c_str(),
|
||||||
|
CurlUnescape(uri_utf8).c_str());
|
||||||
return PathTraitsUTF8::Relative(base.c_str(), uri_utf8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlockingHttpRequest : protected CurlResponseHandler {
|
class BlockingHttpRequest : protected CurlResponseHandler {
|
||||||
|
@ -128,6 +118,10 @@ public:
|
||||||
std::rethrow_exception(postponed_error);
|
std::rethrow_exception(postponed_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CURL *GetEasy() noexcept {
|
||||||
|
return request.Get();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetDone() {
|
void SetDone() {
|
||||||
assert(!done);
|
assert(!done);
|
||||||
|
@ -265,6 +259,8 @@ public:
|
||||||
CommonExpatParser(ExpatNamespaceSeparator{'|'})
|
CommonExpatParser(ExpatNamespaceSeparator{'|'})
|
||||||
{
|
{
|
||||||
request.SetOption(CURLOPT_CUSTOMREQUEST, "PROPFIND");
|
request.SetOption(CURLOPT_CUSTOMREQUEST, "PROPFIND");
|
||||||
|
request.SetOption(CURLOPT_FOLLOWLOCATION, 1l);
|
||||||
|
request.SetOption(CURLOPT_MAXREDIRS, 1l);
|
||||||
|
|
||||||
request_headers.Append(StringFormat<40>("depth: %u", depth));
|
request_headers.Append(StringFormat<40>("depth: %u", depth));
|
||||||
|
|
||||||
|
@ -273,6 +269,7 @@ public:
|
||||||
request.SetOption(CURLOPT_POSTFIELDS,
|
request.SetOption(CURLOPT_POSTFIELDS,
|
||||||
"<?xml version=\"1.0\"?>\n"
|
"<?xml version=\"1.0\"?>\n"
|
||||||
"<a:propfind xmlns:a=\"DAV:\">"
|
"<a:propfind xmlns:a=\"DAV:\">"
|
||||||
|
"<a:prop><a:resourcetype/></a:prop>"
|
||||||
"<a:prop><a:getcontenttype/></a:prop>"
|
"<a:prop><a:getcontenttype/></a:prop>"
|
||||||
"<a:prop><a:getcontentlength/></a:prop>"
|
"<a:prop><a:getcontentlength/></a:prop>"
|
||||||
"</a:propfind>");
|
"</a:propfind>");
|
||||||
|
@ -280,6 +277,7 @@ public:
|
||||||
// TODO: send request body
|
// TODO: send request body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using BlockingHttpRequest::GetEasy;
|
||||||
using BlockingHttpRequest::Wait;
|
using BlockingHttpRequest::Wait;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -450,9 +448,7 @@ CurlStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
|
||||||
{
|
{
|
||||||
// TODO: escape the given URI
|
// TODO: escape the given URI
|
||||||
|
|
||||||
std::string uri = base;
|
const auto uri = MapUTF8(uri_utf8);
|
||||||
uri += uri_utf8;
|
|
||||||
|
|
||||||
return HttpGetInfoOperation(*curl, uri.c_str()).Perform();
|
return HttpGetInfoOperation(*curl, uri.c_str()).Perform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +495,11 @@ private:
|
||||||
if (path == nullptr)
|
if (path == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
path = StringAfterPrefix(path, base_path.c_str());
|
/* kludge: ignoring case in this comparison to avoid
|
||||||
|
false negatives if the web server uses a different
|
||||||
|
case in hex digits in escaped characters; TODO:
|
||||||
|
implement properly */
|
||||||
|
path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
|
||||||
if (path == nullptr || *path == 0)
|
if (path == nullptr || *path == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -525,10 +525,7 @@ protected:
|
||||||
if (escaped_name.IsNull())
|
if (escaped_name.IsNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: unescape
|
entries.emplace_front(CurlUnescape(GetEasy(), escaped_name));
|
||||||
const auto name = escaped_name;
|
|
||||||
|
|
||||||
entries.emplace_front(std::string(name.data, name.size));
|
|
||||||
|
|
||||||
auto &info = entries.front().info;
|
auto &info = entries.front().info;
|
||||||
info = StorageFileInfo(r.collection
|
info = StorageFileInfo(r.collection
|
||||||
|
@ -542,10 +539,7 @@ protected:
|
||||||
std::unique_ptr<StorageDirectoryReader>
|
std::unique_ptr<StorageDirectoryReader>
|
||||||
CurlStorage::OpenDirectory(const char *uri_utf8)
|
CurlStorage::OpenDirectory(const char *uri_utf8)
|
||||||
{
|
{
|
||||||
// TODO: escape the given URI
|
std::string uri = MapUTF8(uri_utf8);
|
||||||
|
|
||||||
std::string uri = base;
|
|
||||||
uri += uri_utf8;
|
|
||||||
|
|
||||||
/* collection URIs must end with a slash */
|
/* collection URIs must end with a slash */
|
||||||
if (uri.back() != '/')
|
if (uri.back() != '/')
|
||||||
|
|
Loading…
Reference in New Issue