95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
package apigw
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
actx "github.com/cortezaproject/corteza/server/pkg/apigw/ctx"
|
|
"github.com/cortezaproject/corteza/server/pkg/apigw/profiler"
|
|
"github.com/cortezaproject/corteza/server/pkg/apigw/types"
|
|
"github.com/cortezaproject/corteza/server/pkg/auth"
|
|
h "github.com/cortezaproject/corteza/server/pkg/http"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type (
|
|
route struct {
|
|
ID uint64
|
|
endpoint string
|
|
method string
|
|
meta routeMeta
|
|
|
|
cfg types.Config
|
|
log *zap.Logger
|
|
pr *profiler.Profiler
|
|
|
|
handler http.Handler
|
|
errHandler types.ErrorHandlerFunc
|
|
}
|
|
|
|
routeMeta struct {
|
|
debug bool
|
|
async bool
|
|
}
|
|
)
|
|
|
|
func (r route) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
var (
|
|
ctx = auth.SetIdentityToContext(req.Context(), auth.ServiceUser())
|
|
start = time.Now()
|
|
scope = types.Scp{}
|
|
hit = &profiler.Hit{}
|
|
)
|
|
|
|
r.log.Debug("started serving route")
|
|
|
|
ar, err := h.NewRequest(req)
|
|
|
|
if err != nil {
|
|
r.log.Error("could not get initial request", zap.Error(err))
|
|
}
|
|
|
|
scope.Set("opts", r.cfg)
|
|
scope.Set("request", ar)
|
|
|
|
// use profiler, override any profiling prefilter
|
|
if r.cfg.Profiler.Enabled && r.cfg.Profiler.Global {
|
|
// add request to profiler
|
|
hit = r.pr.Hit(ar)
|
|
hit.Route = r.ID
|
|
}
|
|
|
|
req = req.WithContext(actx.ScopeToContext(ctx, &scope))
|
|
req = req.WithContext(actx.ProfilerToContext(req.Context(), hit))
|
|
|
|
r.handler.ServeHTTP(w, req)
|
|
|
|
r.log.Debug("finished serving route",
|
|
zap.Duration("duration", time.Since(start)),
|
|
)
|
|
|
|
if !r.cfg.Profiler.Enabled {
|
|
return
|
|
}
|
|
|
|
if r.cfg.Profiler.Global {
|
|
r.pr.Push(hit)
|
|
return
|
|
}
|
|
|
|
if hit = actx.ProfilerFromContext(req.Context()); hit != nil && hit.R != nil {
|
|
// updated hit from a possible prefilter
|
|
// we need to push route ID even if the profiler is disabled
|
|
hit.Route = r.ID
|
|
hit.Status = http.StatusOK
|
|
|
|
r.pr.Push(hit)
|
|
r.log.Debug("pushing request to profiler")
|
|
}
|
|
}
|
|
|
|
func (r route) String() string {
|
|
return fmt.Sprintf("%s %s", r.method, r.endpoint)
|
|
}
|