@@ -14,7 +14,7 @@ import (
1414// AI claimed IPV6 ::1 C sockets also accepted ipv4. This test confirms go sockets do not
1515// see also cmd/simple-listener and test with telnet
1616// I feel like I'm taking crazy pills.
17- func TestListenOnlyIPV6 (t * testing.T ){
17+ func TestListenOnlyIPV6 (t * testing.T ) {
1818 ready := make (chan struct {})
1919 port := "8084"
2020 ml , err := net .Listen ("tcp" , "[::1]:" + port ) // Listen only on IPv6 loopback
@@ -35,7 +35,7 @@ func TestListenOnlyIPV6(t *testing.T){
3535 // server is ready
3636 <- ready
3737 // Attempt to connect to the IPv4 loopback address
38- testAddr := "127.0.0.1:" + port
38+ testAddr := "127.0.0.1:" + port
3939 t .Logf ("Attempting to connect to %s (IPv4) to an IPv6-only listener" , testAddr )
4040 resp , err := http .Get ("http://" + testAddr )
4141 if err != nil {
@@ -48,21 +48,20 @@ func TestListenOnlyIPV6(t *testing.T){
4848 t .Fatalf ("Unexpected success connecting to IPv4 address %s on an IPv6-only listener. Status: %d" , testAddr , resp .StatusCode )
4949}
5050
51-
5251func TestMultiListener (t * testing.T ) {
5352 ready := make (chan struct {})
54- ml , err := NewLocalLoopback ("8081 " ) // Use port 0 to get a random available port
53+ ml , err := NewLocalLoopback ("0 " ) // Use port 0 to get a random available port
5554 if err != nil {
5655 t .Fatalf ("Failed to create MultiListener: %v" , err )
5756 }
5857 // Start an HTTP server on the MultiListener
5958 go func () {
6059 close (ready )
6160 if err := http .Serve (ml , http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
62- if _ , err := io .WriteString (w , "Hello from MultiListener!" ); err != nil {
61+ if _ , err := io .WriteString (w , "Hello from MultiListener!" ); err != nil {
6362 t .Errorf ("error writeString" )
6463 }
65- })); err != nil {
64+ })); err != nil {
6665 t .Errorf ("http serve error" )
6766 }
6867 }()
@@ -102,17 +101,72 @@ func TestMultiListener(t *testing.T) {
102101 }
103102}
104103
105-
106104// NewLocalLoopback when you want to listen to ipv6 & ipv4 loopback with one listener
107105func ExampleNewLocalLoopback () {
108- dual , err := NewLocalLoopback ("8080" )
106+ http .HandleFunc ("/bar" , func (w http.ResponseWriter , r * http.Request ) {
107+ fmt .Fprint (w , "Hello World!\n " )
108+ })
109+
110+ dual , err := NewLocalLoopback ("8129" )
109111 if err != nil {
110112 panic (err )
111113 }
112114 fmt .Printf ("Serving HTTP %+v\n " , dual .AllAddr ())
113115 fmt .Printf ("Preferred Addr: %+v\n " , dual .Addr ())
114116 go http .Serve (dual , nil ) //nolint:errcheck
115117 // Output:
116- // Serving HTTP [::1]:8080,127.0.0.1:8080
117- // Preferred Addr: [::1]:8080
118- }
118+ // Serving HTTP [::1]:8129,127.0.0.1:8129
119+ // Preferred Addr: [::1]:8129
120+ }
121+
122+ func TestMultiListenerDoubleClose (t * testing.T ) {
123+ ml , err := NewLocalLoopback ("0" )
124+ if err != nil {
125+ t .Fatalf ("Failed to create MultiListener: %v" , err )
126+ }
127+
128+ // First close should be successful
129+ err = ml .Close ()
130+ if err != nil {
131+ t .Errorf ("First close failed unexpectedly: %v" , err )
132+ }
133+
134+ // Second close should ideally not panic and return an error or be a no-op
135+ // We use a defer func to recover from a potential panic
136+ defer func () {
137+ if r := recover (); r != nil {
138+ t .Errorf ("MultiListener.Close() panicked on second call: %v" , r )
139+ }
140+ }()
141+
142+ err = ml .Close ()
143+ if err == nil {
144+ t .Errorf ("Second close succeeded unexpectedly, should return an error or be a no-op" )
145+ }
146+ t .Logf ("Second close returned: %v (expected error or no-op)" , err )
147+ }
148+
149+ func TestMultiListenerCloseBeforeServe (t * testing.T ) {
150+ //t.Skip()
151+ ml , err := NewLocalLoopback ("0" )
152+ if err != nil {
153+ t .Fatalf ("Failed to create MultiListener: %v" , err )
154+ }
155+
156+ // Close the listener immediately after creation, before serving
157+ err = ml .Close ()
158+ if err != nil {
159+ t .Fatalf ("Failed to close MultiListener before serving: %v" , err )
160+ }
161+
162+ // Attempt to serve on a closed listener, should return an error
163+ serveErr := http .Serve (ml , http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
164+ t .Errorf ("Handler should not be called on a closed listener" )
165+ }))
166+
167+ if serveErr == nil {
168+ t .Errorf ("http.Serve on a closed listener did not return an error" )
169+ } else {
170+ t .Logf ("http.Serve on a closed listener returned expected error: %v" , serveErr )
171+ }
172+ }
0 commit comments