fix: joinUrl no longer collapses the URL scheme (#2915)

This commit is contained in:
vsaraikin
2026-07-14 22:25:44 +02:00
committed by GitHub
parent aac8c00e99
commit f6f458fe1d
2 changed files with 39 additions and 3 deletions

View File

@@ -3,8 +3,8 @@ package templater
import (
"maps"
"math/rand/v2"
"net/url"
"os"
"path"
"path/filepath"
"runtime"
"strings"
@@ -103,8 +103,13 @@ func joinEnv(elem ...string) string {
return strings.Join(elem, string(os.PathListSeparator))
}
func joinUrl(elem ...string) string {
return path.Join(elem...)
func joinUrl(elem ...string) (string, error) {
if len(elem) == 0 {
return "", nil
}
// Use net/url.JoinPath rather than path.Join: the latter runs path.Clean,
// which collapses the "//" in a URL scheme (e.g. "http://" -> "http:/").
return url.JoinPath(elem[0], elem[1:]...)
}
func merge(base map[string]any, v ...map[string]any) map[string]any {

View File

@@ -0,0 +1,31 @@
package templater
import "testing"
func TestJoinUrl(t *testing.T) {
t.Parallel()
for _, tt := range []struct {
name string
elem []string
want string
}{
// The URL scheme's "//" must be preserved, not collapsed by path.Clean.
{"scheme preserved", []string{"http://localhost", "path1", "path2"}, "http://localhost/path1/path2"},
{"https with base path", []string{"https://example.com/api", "v1", "users"}, "https://example.com/api/v1/users"},
{"trailing slash on base", []string{"http://localhost/", "path"}, "http://localhost/path"},
{"single element", []string{"http://localhost"}, "http://localhost/"},
} {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := joinUrl(tt.elem...)
if err != nil {
t.Fatalf("joinUrl(%q) unexpected error: %v", tt.elem, err)
}
if got != tt.want {
t.Errorf("joinUrl(%q) = %q; want %q", tt.elem, got, tt.want)
}
})
}
}