api/internal/endpoint/handler/http/mock/handler.go

89 lines
1.9 KiB
Go
Raw Normal View History

2021-01-13 17:07:04 +00:00
package mock
import (
"context"
"errors"
"net"
"net/http"
"github.com/soheilhy/cmux"
"gitlab.com/inetmock/inetmock/internal/endpoint"
2021-01-20 18:03:05 +00:00
imHttp "gitlab.com/inetmock/inetmock/internal/endpoint/handler/http"
"gitlab.com/inetmock/inetmock/pkg/logging"
"go.uber.org/zap"
)
const (
name = "http_mock"
handlerNameLblName = "handler_name"
ruleMatchedLblName = "rule_matched"
)
type httpHandler struct {
logger logging.Logger
server *http.Server
}
func (p *httpHandler) Matchers() []cmux.Matcher {
return []cmux.Matcher{cmux.HTTP1()}
}
func (p *httpHandler) Start(lifecycle endpoint.Lifecycle) (err error) {
p.logger = lifecycle.Logger().With(
zap.String("protocol_handler", name),
)
var options httpOptions
if options, err = loadFromConfig(lifecycle); err != nil {
return
}
p.logger = p.logger.With(
zap.String("address", lifecycle.Uplink().Addr().String()),
)
router := &RegexpHandler{
logger: p.logger,
emitter: lifecycle.Audit(),
handlerName: lifecycle.Name(),
}
2021-01-04 16:52:21 +00:00
p.server = &http.Server{
Handler: router,
2021-01-20 18:03:05 +00:00
ConnContext: imHttp.StoreConnPropertiesInContext,
2021-01-04 16:52:21 +00:00
}
for _, rule := range options.Rules {
router.setupRoute(rule)
}
go p.startServer(lifecycle.Uplink().Listener)
go p.shutdownOnCancel(lifecycle.Context())
return
}
func (p *httpHandler) shutdownOnCancel(ctx context.Context) {
<-ctx.Done()
p.logger.Info("Shutting down HTTP mock")
if err := p.server.Close(); err != nil {
p.logger.Error(
"failed to shutdown HTTP server",
zap.Error(err),
)
}
return
}
func (p *httpHandler) startServer(listener net.Listener) {
defer func() {
if err := listener.Close(); err != nil {
p.logger.Warn("failed to close listener", zap.Error(err))
}
}()
if err := p.server.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) {
p.logger.Error(
"failed to start http listener",
zap.Error(err),
)
}
}