@@ -24,6 +24,7 @@ import (
24
24
"net/url"
25
25
"os"
26
26
"strings"
27
+ "sync/atomic"
27
28
"testing"
28
29
"time"
29
30
@@ -58,7 +59,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
58
59
gitImpl git.Implementation
59
60
url string
60
61
branch string
61
- setupGitProxy func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc )
62
+ setupGitProxy func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc )
62
63
shortTimeout bool
63
64
wantUsedProxy bool
64
65
wantError bool
@@ -78,7 +79,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
78
79
gitImpl : gogit .Implementation ,
79
80
url : "http://example.com/bar/test-reponame" ,
80
81
branch : "main" ,
81
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
82
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
82
83
// Create the git server.
83
84
gitServer , err := gittestserver .NewTempGitServer ()
84
85
g .Expect (err ).ToNot (HaveOccurred ())
@@ -101,7 +102,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
101
102
var proxyHandler goproxy.FuncReqHandler = func (req * http.Request , ctx * goproxy.ProxyCtx ) (* http.Request , * http.Response ) {
102
103
userAgent := req .Header .Get ("User-Agent" )
103
104
if strings .Contains (req .Host , "example.com" ) && strings .Contains (userAgent , "git" ) {
104
- * proxyGotRequest = true
105
+ atomic . AddInt32 ( proxiedRequests , 1 )
105
106
req .Host = u .Host
106
107
req .URL .Host = req .Host
107
108
return req , nil
@@ -129,13 +130,13 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
129
130
gitImpl : gogit .Implementation ,
130
131
url : "https://github.com/git-fixtures/basic" ,
131
132
branch : "master" ,
132
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
133
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
133
134
var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
134
135
// We don't check for user agent as this handler is only going to process CONNECT requests, and because Go's net/http
135
136
// is the one making such a request on behalf of go-git, adding a check for the go net/http user agent (Go-http-client)
136
137
// would only allow false positives from any request originating from Go's net/http.
137
138
if strings .Contains (host , "github.com" ) {
138
- * proxyGotRequest = true
139
+ atomic . AddInt32 ( proxiedRequests , 1 )
139
140
return goproxy .OkConnect , host
140
141
}
141
142
// Reject if it isnt our request.
@@ -156,10 +157,10 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
156
157
gitImpl : gogit .Implementation ,
157
158
url : "https://192.0.2.1/bar/test-reponame" ,
158
159
branch : "main" ,
159
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
160
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
160
161
var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
161
162
// We shouldn't hit the proxy so we just want to check for any interaction, then reject.
162
- * proxyGotRequest = true
163
+ atomic . AddInt32 ( proxiedRequests , 1 )
163
164
return goproxy .RejectConnect , host
164
165
}
165
166
proxy .OnRequest ().HandleConnect (proxyHandler )
@@ -175,7 +176,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
175
176
gitImpl : libgit2 .Implementation ,
176
177
url : "https://example.com/bar/test-reponame" ,
177
178
branch : "main" ,
178
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
179
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
179
180
// Create the git server.
180
181
gitServer , err := gittestserver .NewTempGitServer ()
181
182
g .Expect (err ).ToNot (HaveOccurred ())
@@ -210,7 +211,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
210
211
// Check if the host matches with the git server address and the user-agent is the expected git client.
211
212
userAgent := ctx .Req .Header .Get ("User-Agent" )
212
213
if strings .Contains (host , "example.com" ) && strings .Contains (userAgent , "libgit2" ) {
213
- * proxyGotRequest = true
214
+ atomic . AddInt32 ( proxiedRequests , 1 )
214
215
return goproxy .OkConnect , u .Host
215
216
}
216
217
// Reject if it isn't our request.
@@ -238,7 +239,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
238
239
gitImpl : libgit2 .Implementation ,
239
240
url : "http://example.com/bar/test-reponame" ,
240
241
branch : "main" ,
241
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
242
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
242
243
// Create the git server.
243
244
gitServer , err := gittestserver .NewTempGitServer ()
244
245
g .Expect (err ).ToNot (HaveOccurred ())
@@ -258,8 +259,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
258
259
// The certificate used here is valid for both example.com and localhost.
259
260
var proxyHandler goproxy.FuncReqHandler = func (req * http.Request , ctx * goproxy.ProxyCtx ) (* http.Request , * http.Response ) {
260
261
userAgent := req .Header .Get ("User-Agent" )
261
- if strings .Contains (req .Host , "example.com" ) && strings .Contains (userAgent , "libgit2 " ) {
262
- * proxyGotRequest = true
262
+ if strings .Contains (req .Host , "example.com" ) && strings .Contains (userAgent , "git " ) {
263
+ atomic . AddInt32 ( proxiedRequests , 1 )
263
264
req .Host = u .Host
264
265
req .URL .Host = req .Host
265
266
return req , nil
@@ -282,14 +283,41 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
282
283
wantError : false ,
283
284
},
284
285
{
285
- name : "libgit2_NO_PROXY" ,
286
- gitImpl : libgit2 .Implementation ,
286
+ name : "gogit_HTTPS_PROXY" ,
287
+ gitImpl : gogit .Implementation ,
288
+ url : "https://github.com/git-fixtures/basic" ,
289
+ branch : "master" ,
290
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
291
+ var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
292
+ // We don't check for user agent as this handler is only going to process CONNECT requests, and because Go's net/http
293
+ // is the one making such a request on behalf of go-git, adding a check for the go net/http user agent (Go-http-client)
294
+ // would only allow false positives from any request originating from Go's net/http.
295
+ if strings .Contains (host , "github.com" ) {
296
+ atomic .AddInt32 (proxiedRequests , 1 )
297
+ return goproxy .OkConnect , host
298
+ }
299
+ // Reject if it isnt our request.
300
+ return goproxy .RejectConnect , host
301
+ }
302
+ proxy .OnRequest ().HandleConnect (proxyHandler )
303
+
304
+ // go-git does not allow to use an HTTPS proxy and a custom root CA at the same time.
305
+ // See https://github.com/fluxcd/source-controller/pull/524#issuecomment-1006673163.
306
+ return nil , func () {}
307
+ },
308
+ shortTimeout : false ,
309
+ wantUsedProxy : true ,
310
+ wantError : false ,
311
+ },
312
+ {
313
+ name : "gogit_NO_PROXY" ,
314
+ gitImpl : gogit .Implementation ,
287
315
url : "https://192.0.2.1/bar/test-reponame" ,
288
316
branch : "main" ,
289
- setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxyGotRequest * bool ) (* git.AuthOptions , cleanupFunc ) {
317
+ setupGitProxy : func (g * WithT , proxy * goproxy.ProxyHttpServer , proxiedRequests * int32 ) (* git.AuthOptions , cleanupFunc ) {
290
318
var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
291
319
// We shouldn't hit the proxy so we just want to check for any interaction, then reject.
292
- * proxyGotRequest = true
320
+ atomic . AddInt32 ( proxiedRequests , 1 )
293
321
return goproxy .RejectConnect , host
294
322
}
295
323
proxy .OnRequest ().HandleConnect (proxyHandler )
@@ -310,8 +338,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
310
338
proxy := goproxy .NewProxyHttpServer ()
311
339
proxy .Verbose = true
312
340
313
- proxyGotRequest := false
314
- authOpts , cleanup := tt .setupGitProxy (g , proxy , & proxyGotRequest )
341
+ proxiedRequests := int32 ( 0 )
342
+ authOpts , cleanup := tt .setupGitProxy (g , proxy , & proxiedRequests )
315
343
defer cleanup ()
316
344
317
345
proxyServer := http.Server {
@@ -356,7 +384,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
356
384
g .Expect (err ).ToNot (HaveOccurred ())
357
385
}
358
386
359
- g .Expect (proxyGotRequest ).To (Equal (tt .wantUsedProxy ))
387
+ g .Expect (atomic .LoadInt32 (& proxiedRequests ) > 0 ).To (Equal (tt .wantUsedProxy ))
388
+
360
389
})
361
390
}
362
391
}
0 commit comments