patterngoCritical
Combine URL paths with path.Join()
Viewed 0 times
pathswithurlcombinejoinpath
Problem
Is there a way in Go to combine URL paths similarly as we can do with filepaths using
For example see e.g. Combine absolute path and relative path to get a new absolute path.
When I use
See in Golang Playground.
path.Join()?For example see e.g. Combine absolute path and relative path to get a new absolute path.
When I use
path.Join("http://foo", "bar"), I get http:/foo/bar. See in Golang Playground.
Solution
The function path.Join expects a path, not a URL. Parse the URL to get a path and join with that path:
Use the url.JoinPath function in Go 1.19 or later:
Use ResolveReference if you are resolving a URI reference from a base URL. This operation is different from a simple path join: an absolute path in the reference replaces the entire base path; the base path is trimmed back to the last slash before the join operation.
Notice how quux.html in the base URL does not appear in the resolved URL.
u, err := url.Parse("http://foo")
if err != nil { log.Fatal(err) }
u.Path = path.Join(u.Path, "bar.html")
s := u.String()
fmt.Println(s) // prints http://foo/bar.htmlUse the url.JoinPath function in Go 1.19 or later:
s, err := url.JoinPath("http://foo", "bar.html")
if err != nil { log.Fatal(err) }
fmt.Println(s) // prints http://foo/bar.htmlUse ResolveReference if you are resolving a URI reference from a base URL. This operation is different from a simple path join: an absolute path in the reference replaces the entire base path; the base path is trimmed back to the last slash before the join operation.
base, err := url.Parse("http://foo/quux.html")
if err != nil {
log.Fatal(err)
}
ref, err := url.Parse("bar.html")
if err != nil {
log.Fatal(err)
}
u := base.ResolveReference(ref)
fmt.Println(u.String()) // prints http://foo/bar.htmlNotice how quux.html in the base URL does not appear in the resolved URL.
Code Snippets
u, err := url.Parse("http://foo")
if err != nil { log.Fatal(err) }
u.Path = path.Join(u.Path, "bar.html")
s := u.String()
fmt.Println(s) // prints http://foo/bar.htmls, err := url.JoinPath("http://foo", "bar.html")
if err != nil { log.Fatal(err) }
fmt.Println(s) // prints http://foo/bar.htmlbase, err := url.Parse("http://foo/quux.html")
if err != nil {
log.Fatal(err)
}
ref, err := url.Parse("bar.html")
if err != nil {
log.Fatal(err)
}
u := base.ResolveReference(ref)
fmt.Println(u.String()) // prints http://foo/bar.htmlContext
Stack Overflow Q#34668012, score: 170
Revisions (0)
No revisions yet.