api/plugins/http_mock/regex_router.go

90 lines
2.2 KiB
Go
Raw Normal View History

package http_mock
import (
"net/http"
"strconv"
"github.com/prometheus/client_golang/prometheus"
2021-01-04 16:52:21 +00:00
"gitlab.com/inetmock/inetmock/pkg/audit"
2021-01-07 21:00:12 +00:00
details "gitlab.com/inetmock/inetmock/pkg/audit/details"
"gitlab.com/inetmock/inetmock/pkg/logging"
"go.uber.org/zap"
)
type route struct {
rule targetRule
handler http.Handler
}
type RegexpHandler struct {
handlerName string
logger logging.Logger
routes []*route
2021-01-04 16:52:21 +00:00
emitter audit.Emitter
}
func (h *RegexpHandler) Handler(rule targetRule, handler http.Handler) {
h.routes = append(h.routes, &route{rule, handler})
}
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(h.handlerName))
defer timer.ObserveDuration()
for idx := range h.routes {
rule := h.routes[idx].rule
if h.routes[idx].rule.requestMatchTarget.Matches(r, rule.targetKey, rule.pattern) {
totalRequestCounter.WithLabelValues(h.handlerName, strconv.FormatBool(true)).Inc()
h.routes[idx].handler.ServeHTTP(w, r)
return
}
}
// no pattern matched; send 404 response
totalRequestCounter.WithLabelValues(h.handlerName, strconv.FormatBool(false)).Inc()
http.NotFound(w, r)
}
func (h *RegexpHandler) setupRoute(rule targetRule) {
h.logger.Info(
"setup routing",
zap.String("route", rule.Pattern().String()),
zap.String("response", rule.Response()),
)
2021-01-04 16:52:21 +00:00
h.Handler(rule, emittingFileHandler{
emitter: h.emitter,
targetPath: rule.response,
})
}
type emittingFileHandler struct {
emitter audit.Emitter
targetPath string
}
2021-01-04 16:52:21 +00:00
func (f emittingFileHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
f.emitter.Emit(eventFromRequest(request))
http.ServeFile(writer, request, f.targetPath)
}
func eventFromRequest(request *http.Request) audit.Event {
2021-01-07 21:00:12 +00:00
httpDetails := details.HTTP{
2021-01-04 16:52:21 +00:00
Method: request.Method,
Host: request.Host,
URI: request.RequestURI,
Proto: request.Proto,
Headers: request.Header,
}
2021-01-07 21:00:12 +00:00
ev := audit.Event{
2021-01-04 16:52:21 +00:00
Transport: audit.TransportProtocol_TCP,
Application: audit.AppProtocol_HTTP,
2021-01-07 21:00:12 +00:00
ProtocolDetails: httpDetails,
2021-01-04 16:52:21 +00:00
}
2021-01-07 21:00:12 +00:00
ev.SetDestinationIPFromAddr(LocalAddr(request.Context()))
ev.SetSourceIPFromAddr(RemoteAddr(request.Context()))
2021-01-04 16:52:21 +00:00
2021-01-07 21:00:12 +00:00
return ev
}