diff options
-rw-r--r-- | src/lib/curl/Escape.cxx | 55 | ||||
-rw-r--r-- | src/lib/curl/Escape.hxx | 45 | ||||
-rw-r--r-- | src/lib/curl/meson.build | 1 | ||||
-rw-r--r-- | src/storage/plugins/CurlStorage.cxx | 13 |
4 files changed, 103 insertions, 11 deletions
diff --git a/src/lib/curl/Escape.cxx b/src/lib/curl/Escape.cxx new file mode 100644 index 000000000..765de3b94 --- /dev/null +++ b/src/lib/curl/Escape.cxx @@ -0,0 +1,55 @@ +/* + * 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); +} diff --git a/src/lib/curl/Escape.hxx b/src/lib/curl/Escape.hxx new file mode 100644 index 000000000..e09ed8fed --- /dev/null +++ b/src/lib/curl/Escape.hxx @@ -0,0 +1,45 @@ +/* + * 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; + +#endif diff --git a/src/lib/curl/meson.build b/src/lib/curl/meson.build index f66663a01..4d9f534e9 100644 --- a/src/lib/curl/meson.build +++ b/src/lib/curl/meson.build @@ -11,6 +11,7 @@ curl = static_library( 'Init.cxx', 'Global.cxx', 'Request.cxx', + 'Escape.cxx', 'Form.cxx', include_directories: inc, dependencies: [ diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx index 0e6f45a81..803e471d3 100644 --- a/src/storage/plugins/CurlStorage.cxx +++ b/src/storage/plugins/CurlStorage.cxx @@ -28,6 +28,7 @@ #include "lib/curl/String.hxx" #include "lib/curl/Request.hxx" #include "lib/curl/Handler.hxx" +#include "lib/curl/Escape.hxx" #include "lib/expat/ExpatParser.hxx" #include "fs/Traits.hxx" #include "event/Call.hxx" @@ -36,7 +37,6 @@ #include "thread/Cond.hxx" #include "util/ASCII.hxx" #include "util/ChronoUtil.hxx" -#include "util/IterableSplitString.hxx" #include "util/RuntimeError.hxx" #include "util/StringCompare.hxx" #include "util/StringFormat.hxx" @@ -78,16 +78,7 @@ CurlStorage::MapUTF8(const char *uri_utf8) const noexcept if (StringIsEmpty(uri_utf8)) return base; - CurlEasy easy; - std::string path_esc; - - for (auto elt: IterableSplitString(uri_utf8, '/')) { - const auto elt_esc = easy.Escape(elt.data, elt.size); - if (!path_esc.empty()) - path_esc.push_back('/'); - path_esc += elt_esc.c_str(); - } - + std::string path_esc = CurlEscapeUriPath(uri_utf8); return PathTraitsUTF8::Build(base.c_str(), path_esc.c_str()); } |