summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/curl/Escape.cxx55
-rw-r--r--src/lib/curl/Escape.hxx45
-rw-r--r--src/lib/curl/meson.build1
-rw-r--r--src/storage/plugins/CurlStorage.cxx13
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());
}