@@ -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,7 +48,6 @@ 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 {})
5453 ml , err := NewLocalLoopback ("8081" ) // Use port 0 to get a random available port
@@ -59,10 +58,10 @@ func TestMultiListener(t *testing.T) {
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,7 +101,6 @@ 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 () {
108106 dual , err := NewLocalLoopback ("8080" )
@@ -115,4 +113,56 @@ func ExampleNewLocalLoopback() {
115113 // Output:
116114 // Serving HTTP [::1]:8080,127.0.0.1:8080
117115 // Preferred Addr: [::1]:8080
118- }
116+ }
117+
118+ func TestMultiListenerDoubleClose (t * testing.T ) {
119+ ml , err := NewLocalLoopback ("8082" )
120+ if err != nil {
121+ t .Fatalf ("Failed to create MultiListener: %v" , err )
122+ }
123+
124+ // First close should be successful
125+ err = ml .Close ()
126+ if err != nil {
127+ t .Errorf ("First close failed unexpectedly: %v" , err )
128+ }
129+
130+ // Second close should ideally not panic and return an error or be a no-op
131+ // We use a defer func to recover from a potential panic
132+ defer func () {
133+ if r := recover (); r != nil {
134+ t .Errorf ("MultiListener.Close() panicked on second call: %v" , r )
135+ }
136+ }()
137+
138+ err = ml .Close ()
139+ if err == nil {
140+ t .Errorf ("Second close succeeded unexpectedly, should return an error or be a no-op" )
141+ }
142+ t .Logf ("Second close returned: %v (expected error or no-op)" , err )
143+ }
144+
145+ func TestMultiListenerCloseBeforeServe (t * testing.T ) {
146+ t .Skip ()
147+ ml , err := NewLocalLoopback ("8083" )
148+ if err != nil {
149+ t .Fatalf ("Failed to create MultiListener: %v" , err )
150+ }
151+
152+ // Close the listener immediately after creation, before serving
153+ err = ml .Close ()
154+ if err != nil {
155+ t .Fatalf ("Failed to close MultiListener before serving: %v" , err )
156+ }
157+
158+ // Attempt to serve on a closed listener, should return an error
159+ serveErr := http .Serve (ml , http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
160+ t .Errorf ("Handler should not be called on a closed listener" )
161+ }))
162+
163+ if serveErr == nil {
164+ t .Errorf ("http.Serve on a closed listener did not return an error" )
165+ } else {
166+ t .Logf ("http.Serve on a closed listener returned expected error: %v" , serveErr )
167+ }
168+ }
0 commit comments