-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (go version
)?
go version go1.6 darwin/amd64
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/david/dev/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
What did you do?
I wanted to create a URL where a path segment had an encoded slash. This is because usernames in our system are allowed to contain any valid UTF-8 character, and usernames are used in URLs. But getting the url package to properly encode the slash is tricky. Sample code:
username := "foo/bar"
url := url.URL{
Scheme: "https",
Host: "example.com",
Path: "/user/" + username,
}
println(url.String())
What did you expect to see?
https://example.com/user/foo%2Fbar
What did you see instead?
https://example.com/user/foo/bar
Of course I understand that it's impossible for this example to know that "foo/bar" is a single path segment, instead of two. But I tried also supplying a raw path:
username := "foo/bar"
url := url.URL{
Scheme: "https",
Host: "example.com",
Path: "/user/" + username,
RawPath: "user/" + strings.Replace(username, "/", "%2F", -1),
}
println(url.String())
But the output was the same. The only way I've been able to figure out how to get it to know that "foo/bar" is a single segment is by manually encoding each segment myself and then having the url package parse it:
username := "foo/bar"
raw := "https://example.com/user/" + strings.Replace(
(&url.URL{Path: username}).String(),
"/", "%2F", -1,
)
url, err := url.Parse(raw)
if err != nil {
panic(err)
}
println(url.String())
This outputs the correct value:
https://example.com/user/foo%2Fbar
However, since the whole point of constructing a URL from its parts it to generate a string representation (e.g., to pass to http.Get()
), this kind of defeats the whole purpose: I can simply use the raw
variable.
I'd like a way to be able to specify the path as a slice of segments, so that the url package knows which parts are directory segments and which aren't. Something like:
url := url.URL{
Scheme: "https",
Host: "example.com",
Segments: []string{"user", username}
}