frostfs-node/pkg/util/http/server.go

103 lines
2.3 KiB
Go

package httputil
import (
"fmt"
"net/http"
"time"
)
// HTTPSrvPrm groups the required parameters of the Server's constructor.
//
// All values must comply with the requirements imposed on them.
// Passing incorrect parameter values will result in constructor
// failure (error or panic depending on the implementation).
type HTTPSrvPrm struct {
// TCP address for the server to listen on.
//
// Must be a valid TCP address.
Address string
// Must not be nil.
Handler http.Handler
}
// Server represents a wrapper over http.Server
// that provides an interface to start and stop
// listening routine.
//
// For correct operation, Server must be created
// using the constructor (New) based on the required parameters
// and optional components. After successful creation,
// Server is immediately ready to work through API.
type Server struct {
shutdownTimeout time.Duration
srv *http.Server
}
const invalidValFmt = "invalid %s %s (%T): %v"
func panicOnPrmValue(n string, v any) {
panicOnValue("parameter", n, v)
}
func panicOnOptValue(n string, v any) {
panicOnValue("option", n, v)
}
func panicOnValue(t, n string, v any) {
panic(fmt.Sprintf(invalidValFmt, t, n, v, v))
}
func checkSrvPrm(addr string, handler http.Handler) {
switch {
case addr == "":
panicOnPrmValue("Address", addr)
case handler == nil:
panicOnPrmValue("Handler", handler)
}
}
// New creates a new instance of the Server.
//
// Panics if at least one value of the parameters is invalid.
//
// Panics if at least one of next optional parameters is invalid:
// - shutdown timeout is non-positive.
//
// The created Server does not require additional
// initialization and is completely ready for work.
func New(prm HTTPSrvPrm, opts ...Option) *Server {
checkSrvPrm(prm.Address, prm.Handler)
c := defaultCfg()
for _, o := range opts {
o(c)
}
switch {
case c.shutdownTimeout <= 0:
panicOnOptValue("shutdown timeout", c.shutdownTimeout)
}
return &Server{
shutdownTimeout: c.shutdownTimeout,
srv: &http.Server{
Addr: prm.Address,
Handler: prm.Handler,
},
}
}
// NewHTTPSrvPrm creates a new instance of the HTTPSrvPrm.
//
// Panics if at least one value of the parameters is invalid.
func NewHTTPSrvPrm(addr string, handler http.Handler) *HTTPSrvPrm {
checkSrvPrm(addr, handler)
return &HTTPSrvPrm{
Address: addr,
Handler: handler,
}
}