diff --git a/go.sum b/go.sum index bb47ca68..cf6d3661 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,7 @@ golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -93,6 +94,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/hit_test.go b/hit_test.go index b35839e3..fb8d17cc 100644 --- a/hit_test.go +++ b/hit_test.go @@ -719,3 +719,97 @@ func TestNoUserAgent(t *testing.T) { Test(t, Get(s.URL)) } + +func TestJoinURL(t *testing.T) { + tests := []struct { + Params []string + Expected string + }{ + { + []string{ + "http://example.com", + "index.html", + }, + "http://example.com/index.html", + }, + { + []string{ + "http://example.com/", + "index.html", + }, + "http://example.com/index.html", + }, + { + []string{ + "http://example.com", + "/index.html", + }, + "http://example.com/index.html", + }, + { + []string{ + "http://example.com", + "", + }, + "http://example.com", + }, + { + []string{ + "http://example.com/", + "", + }, + "http://example.com", + }, + { + []string{ + "", + "index.html", + }, + "index.html", + }, + { + []string{ + "", + "/index.html", + }, + "/index.html", + }, + { + []string{ + "/index.html", + }, + "/index.html", + }, + { + []string{ + "http://", + "example.com", + "index.html", + }, + "http://example.com/index.html", + }, + { + []string{ + "http://", + "/example.com/", + "/index.html/", + }, + "http://example.com/index.html", + }, + { + []string{ + "example.com", + "index.html", + }, + "example.com/index.html", + }, + } + for i := range tests { + test := tests[i] + t.Run("", func(t *testing.T) { + if s := JoinURL(test.Params...); s != test.Expected { + t.Errorf("expected `%s' got `%s'", test.Expected, s) + } + }) + } +} diff --git a/internal/misc/misc_test.go b/internal/misc/misc_test.go index 9e9be3b1..d854a409 100644 --- a/internal/misc/misc_test.go +++ b/internal/misc/misc_test.go @@ -11,48 +11,68 @@ func TestMakeURL(t *testing.T) { tests := []struct { Base string URL string + Params []interface{} Expected string }{ { "http://example.com", "index.html", + nil, "http://example.com/index.html", }, { "http://example.com/", "index.html", + nil, "http://example.com/index.html", }, { "http://example.com", "/index.html", + nil, "http://example.com/index.html", }, { "http://example.com", "", + nil, "http://example.com", }, { "http://example.com/", "", + nil, "http://example.com/", }, { "", "index.html", + nil, "index.html", }, { "", "/index.html", + nil, "/index.html", }, + { + "http://example.com", + "%s.%s", + []interface{}{"index", "html"}, + "http://example.com/index.html", + }, + { + "http://example.com", + "%s", + nil, + "http://example.com/%s", + }, } for i := range tests { test := tests[i] t.Run("", func(t *testing.T) { - if s := MakeURL(test.Base, test.URL); s != test.Expected { + if s := MakeURL(test.Base, test.URL, test.Params...); s != test.Expected { t.Errorf("expected `%s' got `%s'", test.Expected, s) } }) diff --git a/static.go b/static.go index c7251d3d..5151ee3d 100644 --- a/static.go +++ b/static.go @@ -5,6 +5,7 @@ import ( "io" "net/http" "os" + "strings" "github.com/Eun/go-hit/internal/misc" @@ -566,3 +567,46 @@ func Context(ctx context.Context) IStep { }, } } + +// JoinURL joins the specified parts to one url. +// +// Example: +// JoinURL("https://example.com", "folder", "file") // will return "https://example.com/folder/file" +// JoinURL("https://example.com", "index.html") // will return "https://example.com/index.html" +// JoinURL("https://", "example.com", "index.html") // will return "https://example.com/index.html" +// JoinURL("example.com", "index.html") // will return "example.com/index.html" +// MustDo( +// Get(JoinURL("https://example.com", "index.html")), +// ) +func JoinURL(parts ...string) string { + if len(parts) == 0 { + return "" + } + + notEmptyParts := make([]string, 0, len(parts)) + for _, part := range parts { + if part == "" { + continue + } + notEmptyParts = append(notEmptyParts, part) + } + if len(notEmptyParts) == 0 { + return "" + } + + u, err := urlpkg.Parse(strings.Join(notEmptyParts, "/")) + if err != nil { + return "" + } + + // replace all "double slashes" + for { + old := u.Path + u.Path = strings.ReplaceAll(u.Path, "//", "/") + if old == u.Path { + break + } + } + + return strings.TrimRight(strings.ReplaceAll(u.String(), ":///", "://"), "/") +}