diff --git a/rest/request.go b/rest/request.go index 2f747a28..1ccc0daf 100644 --- a/rest/request.go +++ b/rest/request.go @@ -511,13 +511,23 @@ func (r Request) finalURLTemplate() url.URL { } r.params = newParams url := r.URL() - segments := strings.Split(r.URL().Path, "/") + + segments := strings.Split(url.Path, "/") groupIndex := 0 index := 0 - if r.URL() != nil && r.c.base != nil && strings.Contains(r.URL().Path, r.c.base.Path) { - groupIndex += len(strings.Split(r.c.base.Path, "/")) + trimmedBasePath := "" + if url != nil && r.c.base != nil && strings.Contains(url.Path, r.c.base.Path) { + p := strings.TrimPrefix(url.Path, r.c.base.Path) + if !strings.HasPrefix(p, "/") { + p = "/" + p + } + // store the base path that we have trimmed so we can append it + // before returning the URL + trimmedBasePath = r.c.base.Path + segments = strings.Split(p, "/") + groupIndex = 1 } - if groupIndex >= len(segments) { + if len(segments) <= 2 { return *url } @@ -563,7 +573,7 @@ func (r Request) finalURLTemplate() url.URL { segments[index+3] = "{name}" } } - url.Path = path.Join(segments...) + url.Path = path.Join(trimmedBasePath, path.Join(segments...)) return *url } diff --git a/rest/request_test.go b/rest/request_test.go index e4412f28..645512b7 100644 --- a/rest/request_test.go +++ b/rest/request_test.go @@ -338,6 +338,7 @@ func TestResultIntoWithNoBodyReturnsErr(t *testing.T) { func TestURLTemplate(t *testing.T) { uri, _ := url.Parse("http://localhost/some/base/url/path") + uriSingleSlash, _ := url.Parse("http://localhost/") testCases := []struct { Request *Request ExpectedFullURL string @@ -485,6 +486,38 @@ func TestURLTemplate(t *testing.T) { ExpectedFullURL: "http://localhost/some/base/url/path/pre1/namespaces/namespaces/namespaces/namespaces/namespaces/namespaces/finalize", ExpectedFinalURL: "http://localhost/%7Bprefix%7D", }, + { + // dynamic client with core group + namespace + resourceResource (with name) where baseURL is a single / + // /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME + Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE"). + Prefix("/api/v1/namespaces/ns/r2/name1"), + ExpectedFullURL: "http://localhost/api/v1/namespaces/ns/r2/name1", + ExpectedFinalURL: "http://localhost/api/v1/namespaces/%7Bnamespace%7D/r2/%7Bname%7D", + }, + { + // dynamic client with core group + namespace + resourceResource (with name) where baseURL is 'some/base/url/path' + // /api/$RESOURCEVERSION/namespaces/$NAMESPACE/$RESOURCE/%NAME + Request: NewRequestWithClient(uri, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE"). + Prefix("/api/v1/namespaces/ns/r3/name1"), + ExpectedFullURL: "http://localhost/some/base/url/path/api/v1/namespaces/ns/r3/name1", + ExpectedFinalURL: "http://localhost/some/base/url/path/api/v1/namespaces/%7Bnamespace%7D/r3/%7Bname%7D", + }, + { + // dynamic client where baseURL is a single / + // / + Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE"). + Prefix("/"), + ExpectedFullURL: "http://localhost/", + ExpectedFinalURL: "http://localhost/", + }, + { + // dynamic client where baseURL is a single / + // /version + Request: NewRequestWithClient(uriSingleSlash, "", ClientContentConfig{GroupVersion: schema.GroupVersion{Group: "test"}}, nil).Verb("DELETE"). + Prefix("/version"), + ExpectedFullURL: "http://localhost/version", + ExpectedFinalURL: "http://localhost/version", + }, } for i, testCase := range testCases { r := testCase.Request