[lxc-devel] [lxd/master] Fix file push/pull with names containing spaces
albertodonato on Github
lxc-bot at linuxcontainers.org
Mon Jul 3 09:31:55 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 313 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170703/f85ba481/attachment.bin>
-------------- next part --------------
From 015e52323cb794cd6bc389d6617207c2f0da82bf Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Mon, 3 Jul 2017 11:10:52 +0200
Subject: [PATCH] Fix file push/pull with names containing spaces.
Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
client/lxd_containers.go | 12 ++++++++----
shared/util.go | 11 +++++++++++
shared/util_test.go | 11 +++++++++++
test/suites/filemanip.sh | 11 +++++++++++
4 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/client/lxd_containers.go b/client/lxd_containers.go
index 24a7f2d11..a077afc93 100644
--- a/client/lxd_containers.go
+++ b/client/lxd_containers.go
@@ -471,8 +471,10 @@ func (r *ProtocolLXD) ExecContainer(containerName string, exec api.ContainerExec
// GetContainerFile retrieves the provided path from the container
func (r *ProtocolLXD) GetContainerFile(containerName string, path string) (io.ReadCloser, *ContainerFileResponse, error) {
// Prepare the HTTP request
- url := fmt.Sprintf("%s/1.0/containers/%s/files?path=%s", r.httpHost, containerName, path)
- req, err := http.NewRequest("GET", url, nil)
+ requestUrl := shared.URLEncode(
+ fmt.Sprintf("%s/1.0/containers/%s/files", r.httpHost, containerName),
+ map[string]string{"path": path})
+ req, err := http.NewRequest("GET", requestUrl, nil)
if err != nil {
return nil, nil, err
}
@@ -551,8 +553,10 @@ func (r *ProtocolLXD) CreateContainerFile(containerName string, path string, arg
}
// Prepare the HTTP request
- url := fmt.Sprintf("%s/1.0/containers/%s/files?path=%s", r.httpHost, containerName, path)
- req, err := http.NewRequest("POST", url, args.Content)
+ requestUrl := shared.URLEncode(
+ fmt.Sprintf("%s/1.0/containers/%s/files", r.httpHost, containerName),
+ map[string]string{"path": path})
+ req, err := http.NewRequest("POST", requestUrl, args.Content)
if err != nil {
return err
}
diff --git a/shared/util.go b/shared/util.go
index 43cba2579..a2c4cece0 100644
--- a/shared/util.go
+++ b/shared/util.go
@@ -12,6 +12,7 @@ import (
"io/ioutil"
"math"
"net/http"
+ "net/url"
"os"
"os/exec"
"path"
@@ -28,6 +29,16 @@ import (
const SnapshotDelimiter = "/"
const DefaultPort = "8443"
+// URLEncode encodes a path and query parameters to a URL.
+func URLEncode(path string, query map[string]string) string {
+ params := url.Values{}
+ for key, value := range query {
+ params.Add(key, value)
+ }
+ u := &url.URL{Path: path, RawQuery: params.Encode()}
+ return u.String()
+}
+
// AddSlash adds a slash to the end of paths if they don't already have one.
// This can be useful for rsyncing things, since rsync has behavior present on
// the presence or absence of a trailing slash.
diff --git a/shared/util_test.go b/shared/util_test.go
index 458c8fca9..ea4024683 100644
--- a/shared/util_test.go
+++ b/shared/util_test.go
@@ -9,6 +9,17 @@ import (
"testing"
)
+
+func TestURLEncode(t *testing.T) {
+ url := URLEncode(
+ "/path/with spaces",
+ map[string]string{"param": "with spaces", "other": "without"})
+ expected := "/path/with%20spaces?other=without¶m=with+spaces"
+ if url != expected {
+ t.Error(fmt.Errorf("'%s' != '%s'", url, expected))
+ }
+}
+
func TestFileCopy(t *testing.T) {
helloWorld := []byte("hello world\n")
source, err := ioutil.TempFile("", "")
diff --git a/test/suites/filemanip.sh b/test/suites/filemanip.sh
index d1e8e58c2..2368c9143 100644
--- a/test/suites/filemanip.sh
+++ b/test/suites/filemanip.sh
@@ -36,6 +36,17 @@ test_filemanip() {
lxc exec filemanip -- rm -rf /tmp/ptest/source
+ # Test pushing/pulling a file with spaces
+ echo "foo" > "${TEST_DIR}/source/file with spaces"
+
+ lxc file push -p -r "${TEST_DIR}"/source filemanip/tmp/ptest
+ lxc exec filemanip -- find /tmp/ptest/source | grep -q "file with spaces"
+ rm -rf "${TEST_DIR}/source/file with spaces"
+
+ lxc file pull -p -r filemanip/tmp/ptest "${TEST_DIR}/dest"
+ find "${TEST_DIR}/dest/" | grep "file with spaces"
+ rm -rf "${TEST_DIR}/dest"
+
# Check that file permissions are not applied to intermediate directories
lxc file push -p --mode=400 "${TEST_DIR}"/source/foo \
More information about the lxc-devel
mailing list