diff options
author | Vladimir Shushlin <vshushlin@gitlab.com> | 2021-07-06 10:45:55 +0300 |
---|---|---|
committer | Vladimir Shushlin <vshushlin@gitlab.com> | 2021-07-06 10:45:55 +0300 |
commit | e74c91bfe5c95d6da82691e0c753cc50b661613c (patch) | |
tree | dcdade0e0232dae2b7a895a18ade30275ced131b | |
parent | 59757bc04408388930f2928629c9c12484f3009a (diff) | |
parent | b09cbdbf6560e0e5e7ce20486a0daa077b029516 (diff) |
Merge branch '587-fix-url-path-truncating' into 'master'
Fix path trimming in GitLab client
Closes #587
See merge request gitlab-org/gitlab-pages!512
-rw-r--r-- | internal/source/gitlab/client/client.go | 13 | ||||
-rw-r--r-- | internal/source/gitlab/client/client_test.go | 72 |
2 files changed, 83 insertions, 2 deletions
diff --git a/internal/source/gitlab/client/client.go b/internal/source/gitlab/client/client.go index 182b11ae..2317107f 100644 --- a/internal/source/gitlab/client/client.go +++ b/internal/source/gitlab/client/client.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "net/http" "net/url" + "path" "time" "github.com/dgrijalva/jwt-go" @@ -178,8 +179,16 @@ func (gc *Client) get(ctx context.Context, path string, params url.Values) (*htt return nil, fmt.Errorf("HTTP status: %d", resp.StatusCode) } -func (gc *Client) endpoint(path string, params url.Values) (*url.URL, error) { - endpoint, err := gc.baseURL.Parse(path) +func (gc *Client) endpoint(urlPath string, params url.Values) (*url.URL, error) { + parsedPath, err := url.Parse(urlPath) + if err != nil { + return nil, err + } + + // fix for https://gitlab.com/gitlab-org/gitlab-pages/-/issues/587 + // ensure gc.baseURL.Path is still present and append new urlPath + // it cleans double `/` in either path + endpoint, err := gc.baseURL.Parse(path.Join(gc.baseURL.Path, parsedPath.Path)) if err != nil { return nil, err } diff --git a/internal/source/gitlab/client/client_test.go b/internal/source/gitlab/client/client_test.go index 32fd8c18..ab141730 100644 --- a/internal/source/gitlab/client/client_test.go +++ b/internal/source/gitlab/client/client_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "net/http/httptrace" + "net/url" "testing" "time" @@ -352,3 +353,74 @@ func defaultClient(t *testing.T, url string) *Client { return client } + +// prove fix for https://gitlab.com/gitlab-org/gitlab-pages/-/issues/587 +func Test_endpoint(t *testing.T) { + tests := map[string]struct { + basePath string + urlPath string + params url.Values + expectedURL string + expectedErrMsg string + }{ + "all_slashes": { + basePath: "/", + urlPath: "/", + expectedURL: "/", + }, + "no_host": { + basePath: "/base", + urlPath: "/path", + expectedURL: "/base/path", + }, + "base_url_without_path_and_with_query": { + basePath: "https://gitlab.com", + urlPath: "/api/v4/internal/pages", + params: url.Values{"host": []string{"root.gitlab.io"}}, + expectedURL: "https://gitlab.com/api/v4/internal/pages?host=root.gitlab.io", + }, + "query_in_base_url_ingored": { + basePath: "https://gitlab.com/path?query=true", + urlPath: "/api/v4/internal/pages", + expectedURL: "https://gitlab.com/path/api/v4/internal/pages", + }, + "base_url_with_path_and_with_query": { + basePath: "https://gitlab.com/some/path", + urlPath: "/api/v4/internal/pages", + params: url.Values{"host": []string{"root.gitlab.io"}}, + expectedURL: "https://gitlab.com/some/path/api/v4/internal/pages?host=root.gitlab.io", + }, + "base_url_with_path_ends_in_slash": { + basePath: "https://gitlab.com/some/path/", + urlPath: "/api/v4/internal/pages", + expectedURL: "https://gitlab.com/some/path/api/v4/internal/pages", + }, + "base_url_with_path_no_url_path": { + basePath: "https://gitlab.com/some/path", + urlPath: "", + expectedURL: "https://gitlab.com/some/path", + }, + "url_path_is_not_a_url": { + basePath: "https://gitlab.com", + urlPath: "%", + expectedErrMsg: `parse "%": invalid URL escape "%"`, + }, + } + + for name, tt := range tests { + t.Run(name, func(t *testing.T) { + gc, err := NewClient(tt.basePath, []byte("secret"), defaultClientConnTimeout, defaultJWTTokenExpiry) + require.NoError(t, err) + + got, err := gc.endpoint(tt.urlPath, tt.params) + if tt.expectedErrMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tt.expectedErrMsg) + return + } + + require.NoError(t, err) + require.Equal(t, tt.expectedURL, got.String()) + }) + } +} |