mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
8e7570eee3
* Added environment variable and CLI parameter for adjusting the read buffer size * Changed readBufferSize to int and some bugfixing * Small fixes * ci: 👷 CI system updated * ci: 👷 CI system updated --------- Co-authored-by: Paramtamtam <7326800+tarampampam@users.noreply.github.com>
132 lines
3.6 KiB
Go
132 lines
3.6 KiB
Go
package http
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/fasthttp/router"
|
|
"github.com/valyala/fasthttp"
|
|
"go.uber.org/zap"
|
|
|
|
"gh.tarampamp.am/error-pages/internal/checkers"
|
|
"gh.tarampamp.am/error-pages/internal/config"
|
|
"gh.tarampamp.am/error-pages/internal/http/common"
|
|
errorpageHandler "gh.tarampamp.am/error-pages/internal/http/handlers/errorpage"
|
|
healthzHandler "gh.tarampamp.am/error-pages/internal/http/handlers/healthz"
|
|
indexHandler "gh.tarampamp.am/error-pages/internal/http/handlers/index"
|
|
metricsHandler "gh.tarampamp.am/error-pages/internal/http/handlers/metrics"
|
|
notfoundHandler "gh.tarampamp.am/error-pages/internal/http/handlers/notfound"
|
|
versionHandler "gh.tarampamp.am/error-pages/internal/http/handlers/version"
|
|
"gh.tarampamp.am/error-pages/internal/metrics"
|
|
"gh.tarampamp.am/error-pages/internal/options"
|
|
"gh.tarampamp.am/error-pages/internal/tpl"
|
|
"gh.tarampamp.am/error-pages/internal/version"
|
|
)
|
|
|
|
type Server struct {
|
|
log *zap.Logger
|
|
fast *fasthttp.Server
|
|
router *router.Router
|
|
rdr *tpl.TemplateRenderer
|
|
}
|
|
|
|
const (
|
|
defaultWriteTimeout = time.Second * 4
|
|
defaultReadTimeout = time.Second * 4
|
|
defaultIdleTimeout = time.Second * 6
|
|
)
|
|
|
|
func NewServer(log *zap.Logger, readBufferSize uint) Server {
|
|
rdr := tpl.NewTemplateRenderer()
|
|
|
|
return Server{
|
|
// fasthttp docs: <https://github.com/valyala/fasthttp>
|
|
fast: &fasthttp.Server{
|
|
WriteTimeout: defaultWriteTimeout,
|
|
ReadBufferSize: int(readBufferSize),
|
|
ReadTimeout: defaultReadTimeout,
|
|
IdleTimeout: defaultIdleTimeout,
|
|
NoDefaultServerHeader: true,
|
|
ReduceMemoryUsage: true,
|
|
CloseOnShutdown: true,
|
|
Logger: zap.NewStdLog(log),
|
|
},
|
|
router: router.New(),
|
|
log: log,
|
|
rdr: rdr,
|
|
}
|
|
}
|
|
|
|
// Start server.
|
|
func (s *Server) Start(ip string, port uint16) (err error) {
|
|
if net.ParseIP(ip) == nil {
|
|
return errors.New("invalid IP address")
|
|
}
|
|
|
|
var ln net.Listener
|
|
|
|
if strings.Count(ip, ":") >= 2 { //nolint:gomnd // ipv6
|
|
if ln, err = net.Listen("tcp6", fmt.Sprintf("[%s]:%d", ip, port)); err != nil {
|
|
return err
|
|
}
|
|
} else { // ipv4
|
|
if ln, err = net.Listen("tcp4", fmt.Sprintf("%s:%d", ip, port)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return s.fast.Serve(ln)
|
|
}
|
|
|
|
type templatePicker interface {
|
|
// Pick the template name for responding.
|
|
Pick() string
|
|
}
|
|
|
|
// Register server routes, middlewares, etc.
|
|
// Router docs: <https://github.com/fasthttp/router>
|
|
func (s *Server) Register(cfg *config.Config, templatePicker templatePicker, opt options.ErrorPage) error {
|
|
reg, m := metrics.NewRegistry(), metrics.NewMetrics()
|
|
|
|
if err := m.Register(reg); err != nil {
|
|
return err
|
|
}
|
|
|
|
s.fast.Handler = common.DurationMetrics(common.LogRequest(s.router.Handler, s.log), &m)
|
|
|
|
s.router.GET("/", indexHandler.NewHandler(cfg, templatePicker, s.rdr, opt))
|
|
s.router.GET("/{code}.html", errorpageHandler.NewHandler(cfg, templatePicker, s.rdr, opt))
|
|
|
|
s.router.GET("/version", versionHandler.NewHandler(version.Version()))
|
|
|
|
liveHandler := healthzHandler.NewHandler(checkers.NewLiveChecker())
|
|
s.router.ANY("/healthz", liveHandler)
|
|
s.router.ANY("/health/live", liveHandler) // deprecated
|
|
|
|
s.router.GET("/metrics", metricsHandler.NewHandler(reg))
|
|
|
|
// use index handler to catch all paths? Uses DEFAULT_ERROR_PAGE
|
|
if opt.CatchAll {
|
|
s.router.NotFound = indexHandler.NewHandler(cfg, templatePicker, s.rdr, opt)
|
|
} else {
|
|
// use default not found handler
|
|
s.router.NotFound = notfoundHandler.NewHandler(cfg, templatePicker, s.rdr, opt)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop server.
|
|
func (s *Server) Stop() error {
|
|
if err := s.rdr.Close(); err != nil {
|
|
defer func() { _ = s.fast.Shutdown() }()
|
|
|
|
return err
|
|
}
|
|
|
|
return s.fast.Shutdown()
|
|
}
|