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

88 lines
2 KiB
Go
Raw Normal View History

package httputil
import (
"fmt"
"net/http"
"time"
)
// Prm 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 Prm 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 interface{}) {
panicOnValue("parameter", n, v)
}
func panicOnOptValue(n string, v interface{}) {
panicOnValue("option", n, v)
}
func panicOnValue(t, n string, v interface{}) {
panic(fmt.Sprintf(invalidValFmt, t, n, v, v))
}
// 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 Prm, opts ...Option) *Server {
switch {
case prm.Address == "":
panicOnPrmValue("Address", prm.Address)
case prm.Handler == nil:
panicOnPrmValue("Handler", 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,
},
}
}