@@ -10,7 +10,7 @@ import (
1010 "testing"
1111 "time"
1212
13- "github.com/pires/go-proxyproto"
13+ proxyproto "github.com/pires/go-proxyproto"
1414)
1515
1616// type testListener struct {
@@ -50,6 +50,7 @@ func createProxyClient(proxyAddr, destAddr string, destPort int) *http.Client {
5050
5151 return & http.Client {
5252 Transport : & http.Transport {
53+ DisableKeepAlives : true , // each request uses its own connection; prevents idle-connection races
5354 DialContext : func (ctx context.Context , network , addr string ) (net.Conn , error ) {
5455 conn , err := dialer .Dial (network , proxyAddr )
5556 if err != nil {
@@ -88,6 +89,7 @@ func createBogusProxyClient(proxyAddr, destAddr string, destPort int, version by
8889
8990 cli := & http.Client {
9091 Transport : & http.Transport {
92+ DisableKeepAlives : true , // each request uses its own connection; prevents idle-connection races
9193 DialContext : func (ctx context.Context , network , addr string ) (net.Conn , error ) {
9294 conn , err := dialer .Dial (network , proxyAddr )
9395 if err != nil {
@@ -199,11 +201,16 @@ func TestProxyListenerWithProxyClient(t *testing.T) {
199201
200202 client := createProxyClient (addr , "10.0.0.5" , 8080 )
201203
204+ // shutdownCH is closed after client.Do returns so that srv.Shutdown
205+ // is only called once the request has completed, not on a fixed timer.
206+ shutdownCH := make (chan struct {})
202207 waitShutdownCH := make (chan struct {})
203208 go func () {
204- time . Sleep ( time . Second )
209+ <- shutdownCH
205210 t .Log ("Start shutdown" )
206- if err := srv .Shutdown (context .Background ()); err != nil {
211+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
212+ defer cancel ()
213+ if err := srv .Shutdown (ctx ); err != nil {
207214 t .Logf ("Failed to graceful shutdown: %v" , err )
208215 }
209216 close (waitShutdownCH )
@@ -224,9 +231,13 @@ func TestProxyListenerWithProxyClient(t *testing.T) {
224231 }
225232 req .Host = tt .host
226233 rsp , err := client .Do (req )
234+ close (shutdownCH ) // trigger shutdown now that request has completed or failed
227235 if err != nil && ! tt .wantErr {
228236 t .Fatalf ("Failed to get response: %v" , err )
229237 }
238+ if rsp != nil {
239+ rsp .Body .Close ()
240+ }
230241 if ! tt .wantErr && rsp .StatusCode != tt .want {
231242 t .Fatalf ("Failed to get %d, got %d" , tt .want , rsp .StatusCode )
232243 }
@@ -327,11 +338,14 @@ func TestProxyListenerWithBogusProxyClient(t *testing.T) {
327338
328339 client := createBogusProxyClient (addr , tt .destAddr , 8080 , tt .version , tt .protocol )
329340
341+ shutdownCH := make (chan struct {})
330342 waitShutdownCH := make (chan struct {})
331343 go func () {
332- time . Sleep ( time . Second )
344+ <- shutdownCH
333345 t .Log ("Start shutdown" )
334- if err := srv .Shutdown (context .Background ()); err != nil {
346+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
347+ defer cancel ()
348+ if err := srv .Shutdown (ctx ); err != nil {
335349 t .Logf ("Failed to graceful shutdown: %v" , err )
336350 }
337351 close (waitShutdownCH )
@@ -352,9 +366,13 @@ func TestProxyListenerWithBogusProxyClient(t *testing.T) {
352366 }
353367 req .Host = tt .host
354368 rsp , err := client .Do (req )
369+ close (shutdownCH )
355370 if err != nil && ! tt .wantErr {
356371 t .Fatalf ("Failed to get response: %v" , err )
357372 }
373+ if rsp != nil {
374+ rsp .Body .Close ()
375+ }
358376 if ! tt .wantErr && rsp .StatusCode != tt .want {
359377 t .Fatalf ("Failed to get %d, got %d" , tt .want , rsp .StatusCode )
360378 }
@@ -488,13 +506,20 @@ func TestProxyListenerWithHttpClient(t *testing.T) {
488506 }),
489507 }
490508
491- client := http .DefaultClient
509+ // Use a per-subtest client with keep-alives disabled to prevent
510+ // idle connections from one subtest from contaminating the next.
511+ client := & http.Client {
512+ Transport : & http.Transport {DisableKeepAlives : true },
513+ }
492514
515+ shutdownCH := make (chan struct {})
493516 waitShutdownCH := make (chan struct {})
494517 go func () {
495- time . Sleep ( time . Second )
518+ <- shutdownCH
496519 t .Log ("Start shutdown" )
497- if err := srv .Shutdown (context .Background ()); err != nil {
520+ ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
521+ defer cancel ()
522+ if err := srv .Shutdown (ctx ); err != nil {
498523 t .Logf ("Failed to graceful shutdown: %v" , err )
499524 }
500525 close (waitShutdownCH )
@@ -515,9 +540,13 @@ func TestProxyListenerWithHttpClient(t *testing.T) {
515540 }
516541 req .Host = tt .host
517542 rsp , err := client .Do (req )
543+ close (shutdownCH )
518544 if err != nil && ! tt .wantErr {
519545 t .Fatalf ("Failed to get response: %v" , err )
520546 }
547+ if rsp != nil {
548+ rsp .Body .Close ()
549+ }
521550 if ! tt .wantErr && rsp .StatusCode != tt .want {
522551 t .Fatalf ("Failed to get %d, got %d" , tt .want , rsp .StatusCode )
523552 }
0 commit comments