Add documentation

This commit is contained in:
Balakrishnan Balasubramanian 2023-04-20 17:56:44 -04:00
parent b970ea1c86
commit 175cfa92e9
2 changed files with 32 additions and 10 deletions

View File

@ -9,9 +9,9 @@ Just replace `http.ListenAndServe` with `anyhttp.ListenAndServe`.
+ anyhttp.ListenAndServe(addr, h) + anyhttp.ListenAndServe(addr, h)
``` ```
### Address Syntax ## Address Syntax
#### Unix socket ### Unix socket
Syntax Syntax
@ -22,7 +22,7 @@ Examples
unix/relative/path.sock unix/relative/path.sock
unix//var/run/app/absolutepath.sock unix//var/run/app/absolutepath.sock
#### Systemd Socket activated fd: ### Systemd Socket activated fd:
Syntax Syntax
@ -40,7 +40,7 @@ Examples:
# Using default name # Using default name
sysd/fdname/myapp.socket sysd/fdname/myapp.socket
#### TCP port ### TCP port
If the address is a number less than 65536, it is assumed as a port and passed as `http.ListenAndServe(":<port>",...)` If the address is a number less than 65536, it is assumed as a port and passed as `http.ListenAndServe(":<port>",...)`

View File

@ -13,47 +13,65 @@ import (
"syscall" "syscall"
) )
// UnixSocketConfig has the configuration for Unix socket
type UnixSocketConfig struct { type UnixSocketConfig struct {
SocketPath string
SocketMode fs.FileMode // Absolute or relative path of socket, e.g. /run/app.sock
SocketPath string
// Socket file permission
SocketMode fs.FileMode
// Whether to delete existing socket before creating new one
RemoveExisting bool RemoveExisting bool
} }
// DefaultUnixSocketConfig has defaults for UnixSocketConfig
var DefaultUnixSocketConfig = UnixSocketConfig{ var DefaultUnixSocketConfig = UnixSocketConfig{
SocketMode: 0666, SocketMode: 0666,
RemoveExisting: true, RemoveExisting: true,
} }
// NewUnixSocketConfig creates a UnixSocketConfig with the default values and the socketPath passed
func NewUnixSocketConfig(socketPath string) UnixSocketConfig { func NewUnixSocketConfig(socketPath string) UnixSocketConfig {
usc := DefaultUnixSocketConfig usc := DefaultUnixSocketConfig
usc.SocketPath = socketPath usc.SocketPath = socketPath
return usc return usc
} }
// SysdConfig has the configuration for the socket activated fd
type SysdConfig struct { type SysdConfig struct {
FDIndex *int // Integer value starting at 0. Either index or name is required
FDName *string FDIndex *int
// Name configured via FileDescriptorName or the default socket file name. Either index or name is required
FDName *string
// Check process PID matches LISTEN_PID
CheckPID bool CheckPID bool
// Unsets the LISTEN* environment variables, so they don't get passed to any child processes
UnsetEnv bool UnsetEnv bool
} }
// DefaultSysdConfig has the default values for SysdConfig
var DefaultSysdConfig = SysdConfig{ var DefaultSysdConfig = SysdConfig{
CheckPID: true, CheckPID: true,
UnsetEnv: false, UnsetEnv: false,
} }
// NewSysDConfigWithFDIdx creates SysdConfig with defaults and fdIdx
func NewSysDConfigWithFDIdx(fdIdx int) SysdConfig { func NewSysDConfigWithFDIdx(fdIdx int) SysdConfig {
sysc := DefaultSysdConfig sysc := DefaultSysdConfig
sysc.FDIndex = &fdIdx sysc.FDIndex = &fdIdx
return sysc return sysc
} }
// NewSysDConfigWithFDName creates SysdConfig with defaults and fdName
func NewSysDConfigWithFDName(fdName string) SysdConfig { func NewSysDConfigWithFDName(fdName string) SysdConfig {
sysc := DefaultSysdConfig sysc := DefaultSysdConfig
sysc.FDName = &fdName sysc.FDName = &fdName
return sysc return sysc
} }
// GetListener returns the unix socket listener
func (u *UnixSocketConfig) GetListener() (net.Listener, error) { func (u *UnixSocketConfig) GetListener() (net.Listener, error) {
if u.RemoveExisting { if u.RemoveExisting {
@ -74,6 +92,7 @@ func (u *UnixSocketConfig) GetListener() (net.Listener, error) {
return l, nil return l, nil
} }
// StartFD is the starting file descriptor number
const StartFD = 3 const StartFD = 3
func makeFdListener(fd int, name string) (net.Listener, error) { func makeFdListener(fd int, name string) (net.Listener, error) {
@ -86,6 +105,7 @@ func makeFdListener(fd int, name string) (net.Listener, error) {
return l, nil return l, nil
} }
// GetListener returns the FileListener created with socketed activated fd
func (s *SysdConfig) GetListener() (net.Listener, error) { func (s *SysdConfig) GetListener() (net.Listener, error) {
if s.UnsetEnv { if s.UnsetEnv {
@ -117,9 +137,8 @@ func (s *SysdConfig) GetListener() (net.Listener, error) {
fd := StartFD + idx fd := StartFD + idx
if idx < len(fdNames) { if idx < len(fdNames) {
return makeFdListener(fd, fdNames[idx]) return makeFdListener(fd, fdNames[idx])
} else {
return makeFdListener(fd, fmt.Sprintf("sysdfd_%d", fd))
} }
return makeFdListener(fd, fmt.Sprintf("sysdfd_%d", fd))
} }
if s.FDName != nil { if s.FDName != nil {
@ -159,6 +178,8 @@ func GetListener(addr string) (net.Listener, error) {
return nil, nil return nil, nil
} }
// ListenAndServe is the drop-in replacement for `http.ListenAndServe`.
// Supports unix and systemd sockets in addition
func ListenAndServe(addr string, h http.Handler) error { func ListenAndServe(addr string, h http.Handler) error {
listener, err := GetListener(addr) listener, err := GetListener(addr)
@ -181,6 +202,7 @@ func ListenAndServe(addr string, h http.Handler) error {
return http.ListenAndServe(addr, h) return http.ListenAndServe(addr, h)
} }
// UnsetSystemdListenVars unsets the LISTEN* environment variables so they are not passed to any child processes
func UnsetSystemdListenVars() { func UnsetSystemdListenVars() {
os.Unsetenv("LISTEN_PID") os.Unsetenv("LISTEN_PID")
os.Unsetenv("LISTEN_FDS") os.Unsetenv("LISTEN_FDS")