@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 10, 22:30 UTC

master
go 87 lines 2.33 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //go:build !unix || solaris
16
17 package caddy
18
19 import (
20 "context"
21 "errors"
22 "net"
23 "testing"
24 "time"
25 )
26
27 // TestFakeCloseListenerSiblingSurvivesClose pins that closing one fakeCloseListener
28 // does not wedge another sharing the same socket, as happens during a config reload.
29 func TestFakeCloseListenerSiblingSurvivesClose(t *testing.T) {
30 const network, address = "tcp", "127.0.0.1:0"
31 lnKey := "test|" + network + "/" + address
32
33 ctx := context.Background()
34
35 first, err := listenReusable(ctx, lnKey, network, address, net.ListenConfig{})
36 if err != nil {
37 t.Fatalf("first listen: %v", err)
38 }
39 oldServer := first.(*fakeCloseListener)
40
41 second, err := listenReusable(ctx, lnKey, network, address, net.ListenConfig{})
42 if err != nil {
43 t.Fatalf("second listen: %v", err)
44 }
45 newServer := second.(*fakeCloseListener)
46 defer newServer.Close()
47
48 if err := oldServer.Close(); err != nil {
49 t.Fatalf("close old server: %v", err)
50 }
51
52 addr := newServer.Addr().String()
53
54 // Emulate the net/http accept loop, which retries timeouts as temporary.
55 accepted := make(chan net.Conn, 1)
56 fatal := make(chan error, 1)
57 go func() {
58 for {
59 conn, err := newServer.Accept()
60 if err == nil {
61 accepted <- conn
62 return
63 }
64 var netErr net.Error
65 if errors.As(err, &netErr) && netErr.Timeout() {
66 continue
67 }
68 fatal <- err
69 return
70 }
71 }()
72
73 dialed, err := net.DialTimeout(network, addr, 2*time.Second)
74 if err != nil {
75 t.Fatalf("dial surviving listener: %v", err)
76 }
77 defer dialed.Close()
78
79 select {
80 case conn := <-accepted:
81 conn.Close()
82 case err := <-fatal:
83 t.Fatalf("surviving listener returned a fatal accept error: %v", err)
84 case <-time.After(5 * time.Second):
85 t.Fatal("surviving listener never accepted a connection after its sibling was closed")
86 }
87 }