The Wayback Machine - https://web.archive.org/web/20221017141552/https://github.com/caddyserver/caddy/commit/1960a0dc117dd30fb507b390ddf93b2ef371b9ad
Skip to content
Permalink
Browse files
httpserver: Configurable shutdown delay (#4906)
  • Loading branch information
mholt committed Aug 3, 2022
1 parent 63c7720 commit 1960a0dc117dd30fb507b390ddf93b2ef371b9ad
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 45 deletions.
@@ -190,10 +190,11 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock,

// now that each server is configured, make the HTTP app
httpApp := caddyhttp.App{
HTTPPort: tryInt(options["http_port"], &warnings),
HTTPSPort: tryInt(options["https_port"], &warnings),
GracePeriod: tryDuration(options["grace_period"], &warnings),
Servers: servers,
HTTPPort: tryInt(options["http_port"], &warnings),
HTTPSPort: tryInt(options["https_port"], &warnings),
GracePeriod: tryDuration(options["grace_period"], &warnings),
ShutdownDelay: tryDuration(options["shutdown_delay"], &warnings),
Servers: servers,
}

// then make the TLS app
@@ -31,6 +31,7 @@ func init() {
RegisterGlobalOption("https_port", parseOptHTTPSPort)
RegisterGlobalOption("default_bind", parseOptStringList)
RegisterGlobalOption("grace_period", parseOptDuration)
RegisterGlobalOption("shutdown_delay", parseOptDuration)
RegisterGlobalOption("default_sni", parseOptSingleString)
RegisterGlobalOption("order", parseOptOrder)
RegisterGlobalOption("storage", parseOptStorage)
@@ -3,6 +3,7 @@
http_port 8080
https_port 8443
grace_period 5s
shutdown_delay 10s
default_sni localhost
order root first
storage file_system {
@@ -45,6 +46,7 @@
"http_port": 8080,
"https_port": 8443,
"grace_period": 5000000000,
"shutdown_delay": 10000000000,
"servers": {
"srv0": {
"listen": [
@@ -41,7 +41,7 @@ import (
// the socket have been finished. Always be sure to close listeners
// when you are done with them, just like normal listeners.
func Listen(network, addr string) (net.Listener, error) {
lnKey := network + "/" + addr
lnKey := listenerKey(network, addr)

sharedLn, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
ln, err := net.Listen(network, addr)
@@ -65,7 +65,7 @@ func Listen(network, addr string) (net.Listener, error) {
// It is like Listen except for PacketConns.
// Always be sure to close the PacketConn when you are done.
func ListenPacket(network, addr string) (net.PacketConn, error) {
lnKey := network + "/" + addr
lnKey := listenerKey(network, addr)

sharedPc, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
pc, err := net.ListenPacket(network, addr)
@@ -89,7 +89,7 @@ func ListenPacket(network, addr string) (net.PacketConn, error) {
// Note that the context passed to Accept is currently ignored, so using
// a context other than context.Background is meaningless.
func ListenQUIC(addr string, tlsConf *tls.Config) (quic.EarlyListener, error) {
lnKey := "quic/" + addr
lnKey := listenerKey("udp", addr)

sharedEl, _, err := listenerPool.LoadOrNew(lnKey, func() (Destructor, error) {
el, err := quic.ListenAddrEarly(addr, http3.ConfigureTLSConfig(tlsConf), &quic.Config{})
@@ -106,6 +106,16 @@ func ListenQUIC(addr string, tlsConf *tls.Config) (quic.EarlyListener, error) {
}, err
}

func listenerKey(network, addr string) string {
return network + "/" + addr
}

// ListenerUsage returns the current usage count of the given listener address.
func ListenerUsage(network, addr string) int {
count, _ := listenerPool.References(listenerKey(network, addr))
return count
}

// fakeCloseListener is a private wrapper over a listener that
// is shared. The state of fakeCloseListener is not shared.
// This allows one user of a socket to "close" the listener
@@ -353,11 +363,25 @@ func (na NetworkAddress) JoinHostPort(offset uint) string {
return net.JoinHostPort(na.Host, strconv.Itoa(int(na.StartPort+offset)))
}

func (na NetworkAddress) Expand() []NetworkAddress {
size := na.PortRangeSize()
addrs := make([]NetworkAddress, size)
for portOffset := uint(0); portOffset < size; portOffset++ {
na2 := na
na2.StartPort, na2.EndPort = na.StartPort+portOffset, na.StartPort+portOffset
addrs[portOffset] = na2
}
return addrs
}

// PortRangeSize returns how many ports are in
// pa's port range. Port ranges are inclusive,
// so the size is the difference of start and
// end ports plus one.
func (na NetworkAddress) PortRangeSize() uint {
if na.EndPort < na.StartPort {
return 0
}
return (na.EndPort - na.StartPort) + 1
}

@@ -331,3 +331,85 @@ func TestJoinHostPort(t *testing.T) {
}
}
}

func TestExpand(t *testing.T) {
for i, tc := range []struct {
input NetworkAddress
expect []NetworkAddress
}{
{
input: NetworkAddress{
Network: "tcp",
Host: "localhost",
StartPort: 2000,
EndPort: 2000,
},
expect: []NetworkAddress{
{
Network: "tcp",
Host: "localhost",
StartPort: 2000,
EndPort: 2000,
},
},
},
{
input: NetworkAddress{
Network: "tcp",
Host: "localhost",
StartPort: 2000,
EndPort: 2002,
},
expect: []NetworkAddress{
{
Network: "tcp",
Host: "localhost",
StartPort: 2000,
EndPort: 2000,
},
{
Network: "tcp",
Host: "localhost",
StartPort: 2001,
EndPort: 2001,
},
{
Network: "tcp",
Host: "localhost",
StartPort: 2002,
EndPort: 2002,
},
},
},
{
input: NetworkAddress{
Network: "tcp",
Host: "localhost",
StartPort: 2000,
EndPort: 1999,
},
expect: []NetworkAddress{},
},
{
input: NetworkAddress{
Network: "unix",
Host: "/foo/bar",
StartPort: 0,
EndPort: 0,
},
expect: []NetworkAddress{
{
Network: "unix",
Host: "/foo/bar",
StartPort: 0,
EndPort: 0,
},
},
},
} {
actual := tc.input.Expand()
if !reflect.DeepEqual(actual, tc.expect) {
t.Errorf("Test %d: Expected %+v but got %+v", i, tc.expect, actual)
}
}
}

0 comments on commit 1960a0d

Please sign in to comment.