From 29f78b18b1dd77afd517a519afe4acd23dd76407 Mon Sep 17 00:00:00 2001
From: Joshua Wise <joshua@joshuawise.com>
Date: Fri, 17 Aug 2018 14:41:29 -0400
Subject: [PATCH] storage/plugins/CurlStorage: URL-encode paths in
 CurlStorage::MapUTF8

When using a database that was not created with a WebDAV music_directory
(i.e., if using a remote database, on which updates happen locally) and
using the Curl storage plugin, MPD would previously send GET requests that
had unescaped spaces in them.  This change uses Curl's URL-encode API to
solve this.
---
 NEWS                                |  2 ++
 src/storage/plugins/CurlStorage.cxx | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index a1a7475d0..972b7144a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
 ver 0.20.22 (not yet released)
+* storage
+  - curl: URL-encode paths
 
 ver 0.20.21 (2018/08/17)
 * database
diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx
index 8e99f5c56..f2d61772e 100644
--- a/src/storage/plugins/CurlStorage.cxx
+++ b/src/storage/plugins/CurlStorage.cxx
@@ -34,6 +34,7 @@
 #include "thread/Mutex.hxx"
 #include "thread/Cond.hxx"
 #include "util/ASCII.hxx"
+#include "util/IterableSplitString.hxx"
 #include "util/RuntimeError.hxx"
 #include "util/StringCompare.hxx"
 #include "util/StringFormat.hxx"
@@ -79,9 +80,18 @@ CurlStorage::MapUTF8(const char *uri_utf8) const noexcept
 	if (StringIsEmpty(uri_utf8))
 		return base;
 
-	// TODO: escape the given URI
+	CurlEasy easy;
+	std::string path_esc;
 
-	return PathTraitsUTF8::Build(base.c_str(), uri_utf8);
+	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());
 }
 
 const char *