-
Notifications
You must be signed in to change notification settings - Fork 8
/
middleware.go
85 lines (70 loc) · 2.31 KB
/
middleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package middleware
import (
"fmt"
"github.com/b2wdigital/restQL-golang/v4/internal/platform/conf"
"github.com/b2wdigital/restQL-golang/v4/internal/platform/plugins"
"github.com/b2wdigital/restQL-golang/v4/pkg/restql"
"github.com/valyala/fasthttp"
)
// Middleware defines a generic handler wrapper
// capable of controlling request flow.
type Middleware interface {
Apply(h fasthttp.RequestHandler) fasthttp.RequestHandler
}
type noopMiddleware struct{}
func (nm noopMiddleware) Apply(h fasthttp.RequestHandler) fasthttp.RequestHandler {
return h
}
// Decorator is a type responsible for wrapping handlers
// with default and config enabled middlewares.
type Decorator struct {
log restql.Logger
cfg *conf.Config
pm plugins.Lifecycle
cm *ConnManager
}
// NewDecorator creates a middleware Decorator
func NewDecorator(log restql.Logger, cfg *conf.Config, pm plugins.Lifecycle) *Decorator {
cmEnabled := cfg.HTTP.Server.Middlewares.RequestCancellation.Enabled
cmWatchingInterval := cfg.HTTP.Server.Middlewares.RequestCancellation.WatchInterval
return &Decorator{
log: log,
cfg: cfg,
pm: pm,
cm: NewConnManager(log, cmEnabled, cmWatchingInterval),
}
}
// Apply takes a base handler and fetches all middlewares enabled in configuration
// decorating the argument with each one.
func (d *Decorator) Apply(h fasthttp.RequestHandler) fasthttp.RequestHandler {
mws := d.fetchEnabled()
handler := h
for i := len(mws) - 1; i >= 0; i-- {
m := mws[i]
d.log.Debug(fmt.Sprintf("applying middleware %T", m))
handler = m.Apply(handler)
}
return handler
}
func (d *Decorator) fetchEnabled() []Middleware {
mws := []Middleware{newRecoverer(d.log), newNativeContext(d.cm), newTransaction(d.pm)}
mwCfg := d.cfg.HTTP.Server.Middlewares
if mwCfg.Timeout != nil {
mws = append(mws, newTimeout(mwCfg.Timeout.Duration, d.log))
}
if mwCfg.RequestID != nil {
mws = append(mws, newRequestID(mwCfg.RequestID.Header, mwCfg.RequestID.Strategy, d.log))
}
if mwCfg.Cors != nil {
cors := newCors(d.log, corsOptions{
AllowedOrigins: mwCfg.Cors.AllowOrigin,
AllowedMethods: mwCfg.Cors.AllowMethods,
AllowedHeaders: mwCfg.Cors.AllowHeaders,
ExposedHeaders: mwCfg.Cors.ExposeHeaders,
MaxAge: mwCfg.Cors.MaxAge,
AllowCredentials: mwCfg.Cors.AllowCredentials,
})
mws = append(mws, cors)
}
return mws
}