@@ -24,6 +24,7 @@ import (
2424 "net/url"
2525 "os"
2626 "strings"
27+ "sync/atomic"
2728 "testing"
2829 "time"
2930
@@ -58,7 +59,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
5859 gitImpl git.Implementation
5960 url string
6061 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 )
6263 shortTimeout bool
6364 wantUsedProxy bool
6465 wantError bool
@@ -78,7 +79,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
7879 gitImpl : gogit .Implementation ,
7980 url : "http://example.com/bar/test-reponame" ,
8081 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 ) {
8283 // Create the git server.
8384 gitServer , err := gittestserver .NewTempGitServer ()
8485 g .Expect (err ).ToNot (HaveOccurred ())
@@ -101,7 +102,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
101102 var proxyHandler goproxy.FuncReqHandler = func (req * http.Request , ctx * goproxy.ProxyCtx ) (* http.Request , * http.Response ) {
102103 userAgent := req .Header .Get ("User-Agent" )
103104 if strings .Contains (req .Host , "example.com" ) && strings .Contains (userAgent , "git" ) {
104- * proxyGotRequest = true
105+ atomic . AddInt32 ( proxiedRequests , 1 )
105106 req .Host = u .Host
106107 req .URL .Host = req .Host
107108 return req , nil
@@ -129,13 +130,13 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
129130 gitImpl : gogit .Implementation ,
130131 url : "https://github.com/git-fixtures/basic" ,
131132 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 ) {
133134 var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
134135 // We don't check for user agent as this handler is only going to process CONNECT requests, and because Go's net/http
135136 // 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)
136137 // would only allow false positives from any request originating from Go's net/http.
137138 if strings .Contains (host , "github.com" ) {
138- * proxyGotRequest = true
139+ atomic . AddInt32 ( proxiedRequests , 1 )
139140 return goproxy .OkConnect , host
140141 }
141142 // Reject if it isnt our request.
@@ -156,10 +157,10 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
156157 gitImpl : gogit .Implementation ,
157158 url : "https://192.0.2.1/bar/test-reponame" ,
158159 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 ) {
160161 var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
161162 // 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 )
163164 return goproxy .RejectConnect , host
164165 }
165166 proxy .OnRequest ().HandleConnect (proxyHandler )
@@ -175,7 +176,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
175176 gitImpl : libgit2 .Implementation ,
176177 url : "https://example.com/bar/test-reponame" ,
177178 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 ) {
179180 // Create the git server.
180181 gitServer , err := gittestserver .NewTempGitServer ()
181182 g .Expect (err ).ToNot (HaveOccurred ())
@@ -210,7 +211,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
210211 // Check if the host matches with the git server address and the user-agent is the expected git client.
211212 userAgent := ctx .Req .Header .Get ("User-Agent" )
212213 if strings .Contains (host , "example.com" ) && strings .Contains (userAgent , "libgit2" ) {
213- * proxyGotRequest = true
214+ atomic . AddInt32 ( proxiedRequests , 1 )
214215 return goproxy .OkConnect , u .Host
215216 }
216217 // Reject if it isn't our request.
@@ -238,7 +239,7 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
238239 gitImpl : libgit2 .Implementation ,
239240 url : "http://example.com/bar/test-reponame" ,
240241 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 ) {
242243 // Create the git server.
243244 gitServer , err := gittestserver .NewTempGitServer ()
244245 g .Expect (err ).ToNot (HaveOccurred ())
@@ -258,8 +259,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
258259 // The certificate used here is valid for both example.com and localhost.
259260 var proxyHandler goproxy.FuncReqHandler = func (req * http.Request , ctx * goproxy.ProxyCtx ) (* http.Request , * http.Response ) {
260261 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 )
263264 req .Host = u .Host
264265 req .URL .Host = req .Host
265266 return req , nil
@@ -282,14 +283,41 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
282283 wantError : false ,
283284 },
284285 {
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 ,
287315 url : "https://192.0.2.1/bar/test-reponame" ,
288316 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 ) {
290318 var proxyHandler goproxy.FuncHttpsHandler = func (host string , ctx * goproxy.ProxyCtx ) (* goproxy.ConnectAction , string ) {
291319 // 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 )
293321 return goproxy .RejectConnect , host
294322 }
295323 proxy .OnRequest ().HandleConnect (proxyHandler )
@@ -310,8 +338,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
310338 proxy := goproxy .NewProxyHttpServer ()
311339 proxy .Verbose = true
312340
313- proxyGotRequest := false
314- authOpts , cleanup := tt .setupGitProxy (g , proxy , & proxyGotRequest )
341+ proxiedRequests := int32 ( 0 )
342+ authOpts , cleanup := tt .setupGitProxy (g , proxy , & proxiedRequests )
315343 defer cleanup ()
316344
317345 proxyServer := http.Server {
@@ -356,7 +384,8 @@ func TestCheckoutStrategyForImplementation_Proxied(t *testing.T) {
356384 g .Expect (err ).ToNot (HaveOccurred ())
357385 }
358386
359- g .Expect (proxyGotRequest ).To (Equal (tt .wantUsedProxy ))
387+ g .Expect (atomic .LoadInt32 (& proxiedRequests ) > 0 ).To (Equal (tt .wantUsedProxy ))
388+
360389 })
361390 }
362391}
0 commit comments