Skip to content

Commit 0f7fbc9

Browse files
committed
fix: Fix base url regression to ensure trailing /
Signed-off-by: Steve Hipwell <[email protected]>
1 parent a3b39ed commit 0f7fbc9

2 files changed

Lines changed: 144 additions & 8 deletions

File tree

github/config.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package github
22

33
import (
44
"context"
5-
"fmt"
65
"net/http"
76
"net/url"
87
"path"
@@ -45,6 +44,9 @@ const DotComHost = "api.github.com"
4544
// https://[hostname].ghe.com/ instances expect paths that behave similar to GitHub.com, not GitHub Enterprise Server.
4645
var GHECDataResidencyHostMatch = regexp.MustCompile(`^[a-zA-Z0-9.\-]+\.ghe\.com\/?$`)
4746

47+
// GHESAPISuffixMatch is a regex to match GitHub Enterprise Server API suffixes.
48+
var GHESAPISuffixMatch = regexp.MustCompile(`api/v3\/?$`)
49+
4850
func RateLimitedHTTPClient(client *http.Client, writeDelay, readDelay, retryDelay time.Duration, parallelRequests bool, retryableErrors map[int]bool, maxRetries int) *http.Client {
4951
client.Transport = NewEtagTransport(client.Transport)
5052
client.Transport = NewRateLimitTransport(client.Transport, WithWriteDelay(writeDelay), WithReadDelay(readDelay), WithParallelRequests(parallelRequests))
@@ -103,16 +105,15 @@ func (c *Config) NewRESTClient(client *http.Client) (*github.Client, error) {
103105
}
104106

105107
hostname := uv3.Hostname()
106-
if hostname != DotComHost && !GHECDataResidencyHostMatch.MatchString(hostname) {
107-
uv3.Path = fmt.Sprintf("%s/", path.Join(uv3.Path, "api/v3"))
108-
}
109-
110-
v3client, err := github.NewClient(client).WithEnterpriseURLs(uv3.String(), "")
111-
if err != nil {
112-
return nil, err
108+
if hostname != DotComHost && !GHECDataResidencyHostMatch.MatchString(hostname) && !GHESAPISuffixMatch.MatchString(uv3.Path) {
109+
uv3.Path = path.Join(uv3.Path, "api/v3/")
113110
}
114111

112+
v3client := github.NewClient(client)
115113
v3client.BaseURL = uv3
114+
if !strings.HasSuffix(v3client.BaseURL.Path, "/") {
115+
v3client.BaseURL.Path += "/"
116+
}
116117

117118
return v3client, nil
118119
}

github/config_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,141 @@ func TestGHECDataResidencyHostMatch(t *testing.T) {
6565
}
6666
}
6767

68+
func TestConfigMeta(t *testing.T) {
69+
dotcomURL := "https://api.github.com/"
70+
ghecURL := "https://customer.ghe.com/"
71+
ghesURL := "https://example.com/api/v3/"
72+
ghesPathURL := "https://example.com/test/api/v3/"
73+
74+
t.Run("returns a v3 rest api client for dotcom", func(t *testing.T) {
75+
config := Config{
76+
BaseURL: dotcomURL,
77+
}
78+
meta, err := config.Meta()
79+
if err != nil {
80+
t.Fatalf("failed to return meta without error: %s", err.Error())
81+
}
82+
83+
client := meta.(*Owner).v3client
84+
got := client.BaseURL.String()
85+
if got != dotcomURL {
86+
t.Fatalf("expected base URL %q, got %q", dotcomURL, got)
87+
}
88+
})
89+
90+
t.Run("returns a v3 rest api client for dotcom with a base url missing a slash", func(t *testing.T) {
91+
config := Config{
92+
BaseURL: "https://api.github.com",
93+
}
94+
meta, err := config.Meta()
95+
if err != nil {
96+
t.Fatalf("failed to return meta without error: %s", err.Error())
97+
}
98+
99+
client := meta.(*Owner).v3client
100+
got := client.BaseURL.String()
101+
if got != dotcomURL {
102+
t.Fatalf("expected base URL %q, got %q", dotcomURL, got)
103+
}
104+
})
105+
106+
t.Run("returns a v3 rest api client for ghec", func(t *testing.T) {
107+
config := Config{
108+
BaseURL: ghecURL,
109+
}
110+
meta, err := config.Meta()
111+
if err != nil {
112+
t.Fatalf("failed to return meta without error: %s", err.Error())
113+
}
114+
115+
client := meta.(*Owner).v3client
116+
got := client.BaseURL.String()
117+
if got != ghecURL {
118+
t.Fatalf("expected base URL %q, got %q", ghecURL, got)
119+
}
120+
})
121+
122+
t.Run("returns a v3 rest api client for ghec with a base url missing a slash", func(t *testing.T) {
123+
config := Config{
124+
BaseURL: "https://customer.ghe.com",
125+
}
126+
meta, err := config.Meta()
127+
if err != nil {
128+
t.Fatalf("failed to return meta without error: %s", err.Error())
129+
}
130+
131+
client := meta.(*Owner).v3client
132+
got := client.BaseURL.String()
133+
if got != ghecURL {
134+
t.Fatalf("expected base URL %q, got %q", ghecURL, got)
135+
}
136+
})
137+
138+
t.Run("returns a v3 rest api client for ghes with the api suffix", func(t *testing.T) {
139+
config := Config{
140+
BaseURL: ghesURL,
141+
}
142+
meta, err := config.Meta()
143+
if err != nil {
144+
t.Fatalf("failed to return meta without error: %s", err.Error())
145+
}
146+
147+
client := meta.(*Owner).v3client
148+
got := client.BaseURL.String()
149+
if got != ghesURL {
150+
t.Fatalf("expected base URL %q, got %q", ghesURL, got)
151+
}
152+
})
153+
154+
t.Run("returns a v3 rest api client for ghes with the api suffix missing a slash", func(t *testing.T) {
155+
config := Config{
156+
BaseURL: "https://example.com/api/v3",
157+
}
158+
meta, err := config.Meta()
159+
if err != nil {
160+
t.Fatalf("failed to return meta without error: %s", err.Error())
161+
}
162+
163+
client := meta.(*Owner).v3client
164+
got := client.BaseURL.String()
165+
if got != ghesURL {
166+
t.Fatalf("expected base URL %q, got %q", ghesURL, got)
167+
}
168+
})
169+
170+
t.Run("returns a v3 rest api client for ghes", func(t *testing.T) {
171+
config := Config{
172+
BaseURL: "https://example.com/",
173+
}
174+
meta, err := config.Meta()
175+
if err != nil {
176+
t.Fatalf("failed to return meta without error: %s", err.Error())
177+
}
178+
179+
client := meta.(*Owner).v3client
180+
got := client.BaseURL.String()
181+
if got != ghesURL {
182+
t.Fatalf("expected base URL %q, got %q", ghesURL, got)
183+
}
184+
})
185+
186+
t.Run("returns a v3 rest api client for ghes with a path", func(t *testing.T) {
187+
config := Config{
188+
BaseURL: ghesPathURL,
189+
}
190+
meta, err := config.Meta()
191+
if err != nil {
192+
t.Fatalf("failed to return meta without error: %s", err.Error())
193+
}
194+
195+
client := meta.(*Owner).v3client
196+
got := client.BaseURL.String()
197+
if got != ghesPathURL {
198+
t.Fatalf("expected base URL %q, got %q", ghesPathURL, got)
199+
}
200+
})
201+
}
202+
68203
func TestAccConfigMeta(t *testing.T) {
69204
// FIXME: Skip test runs during travis lint checking
70205
if testToken == "" {

0 commit comments

Comments
 (0)