diff options
author | Matthew Holt <[email protected]> | 2019-03-26 15:45:51 -0600 |
---|---|---|
committer | Matthew Holt <[email protected]> | 2019-03-26 15:45:51 -0600 |
commit | 86e2d1b0a48fbd84590291969611f1870471c3e0 (patch) | |
tree | d3a8d82ca88f7d7ff60476cd772d8c4314cd6a3f /listeners.go | |
parent | 859b5d7ea3b8f660ac68d9aea5a53d25a9a7422c (diff) | |
download | caddy-86e2d1b0a48fbd84590291969611f1870471c3e0.tar.gz caddy-86e2d1b0a48fbd84590291969611f1870471c3e0.zip |
Rudimentary start of HTTP servers
Diffstat (limited to 'listeners.go')
-rw-r--r-- | listeners.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/listeners.go b/listeners.go new file mode 100644 index 000000000..962cb1d25 --- /dev/null +++ b/listeners.go @@ -0,0 +1,51 @@ +package caddy2 + +import ( + "fmt" + "net" + "sync/atomic" +) + +// Listen returns a listener suitable for use in a Caddy module. +func Listen(proto, addr string) (net.Listener, error) { + ln, err := net.Listen(proto, addr) + if err != nil { + return nil, err + } + return &fakeCloseListener{Listener: ln}, nil +} + +// fakeCloseListener's Close() method is a no-op. This allows +// stopping servers that are using the listener without giving +// up the socket; thus, servers become hot-swappable while the +// listener remains running. Listeners should be re-wrapped in +// a new fakeCloseListener each time the listener is reused. +type fakeCloseListener struct { + closed int32 + net.Listener +} + +// Accept accepts connections until Close() is called. +func (fcl *fakeCloseListener) Accept() (net.Conn, error) { + if atomic.LoadInt32(&fcl.closed) == 1 { + return nil, ErrSwappingServers + } + return fcl.Listener.Accept() +} + +// Close stops accepting new connections, but does not +// actually close the underlying listener. +func (fcl *fakeCloseListener) Close() error { + atomic.StoreInt32(&fcl.closed, 1) + return nil +} + +// CloseUnderlying actually closes the underlying listener. +func (fcl *fakeCloseListener) CloseUnderlying() error { + return fcl.Listener.Close() +} + +// ErrSwappingServers is returned by fakeCloseListener when +// Close() is called, indicating that it is pretending to +// be closed so that the server using it can terminate. +var ErrSwappingServers = fmt.Errorf("listener 'closed' 😉") |