mirror of
https://github.com/rclone/rclone.git
synced 2025-10-06 05:47:10 +02:00
lib/rest: add URLPathEscapeAll to URL escape as many chars as possible
This commit is contained in:
@@ -3,6 +3,7 @@ package rest
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// URLJoin joins a URL and a path returning a new URL
|
// URLJoin joins a URL and a path returning a new URL
|
||||||
@@ -24,3 +25,24 @@ func URLPathEscape(in string) string {
|
|||||||
u.Path = in
|
u.Path = in
|
||||||
return u.String()
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLPathEscapeAll escapes URL path the in string using URL escaping rules
|
||||||
|
//
|
||||||
|
// It escapes every character except [A-Za-z0-9] and /
|
||||||
|
func URLPathEscapeAll(in string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.Grow(len(in) * 3) // worst case: every byte escaped
|
||||||
|
const hex = "0123456789ABCDEF"
|
||||||
|
for i := range len(in) {
|
||||||
|
c := in[i]
|
||||||
|
if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
||||||
|
(c >= '0' && c <= '9') || c == '/' {
|
||||||
|
b.WriteByte(c)
|
||||||
|
} else {
|
||||||
|
b.WriteByte('%')
|
||||||
|
b.WriteByte(hex[c>>4])
|
||||||
|
b.WriteByte(hex[c&0x0F])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
@@ -59,3 +59,27 @@ func TestURLPathEscape(t *testing.T) {
|
|||||||
assert.Equal(t, test.want, got, fmt.Sprintf("Test %d path = %q", i, test.path))
|
assert.Equal(t, test.want, got, fmt.Sprintf("Test %d path = %q", i, test.path))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestURLPathEscapeAll(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"", ""},
|
||||||
|
{"/hello.txt", "/hello%2Etxt"},
|
||||||
|
{"With Space", "With%20Space"},
|
||||||
|
{"With Colon:", "With%20Colon%3A"},
|
||||||
|
{"With Percent%", "With%20Percent%25"},
|
||||||
|
{"abc/XYZ123", "abc/XYZ123"},
|
||||||
|
{"hello world", "hello%20world"},
|
||||||
|
{"$test", "%24test"},
|
||||||
|
{"ümlaut", "%C3%BCmlaut"},
|
||||||
|
{"", ""},
|
||||||
|
{" /?", "%20/%3F"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
got := URLPathEscapeAll(test.in)
|
||||||
|
assert.Equal(t, test.want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user