mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-16 23:35:20 +01:00
feat: skip middlewares require db for ping
The ping endpoint will be blocked when DB conns reach the max open conns of the sql.DB which will make ping request timeout, so skip the middlewares which will require DB conn. Signed-off-by: He Weiwei <hweiwei@vmware.com>
This commit is contained in:
parent
9a38dca1a6
commit
0c5aedb3d9
@ -214,7 +214,7 @@ func init() {
|
||||
mockServer := test.NewJobServiceServer()
|
||||
defer mockServer.Close()
|
||||
|
||||
chain := middleware.Chain(orm.Middleware(), security.Middleware())
|
||||
chain := middleware.Chain(orm.Middleware(), security.Middleware(), security.UnauthorizedMiddleware())
|
||||
handler = chain(beego.BeeApp.Handlers)
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,10 @@ var (
|
||||
match = regexp.MustCompile
|
||||
numericRegexp = match(`[0-9]+`)
|
||||
|
||||
// The ping endpoint will be blocked when DB conns reach the max open conns of the sql.DB
|
||||
// which will make ping request timeout, so skip the middlewares which will require DB conn.
|
||||
pingSkipper = middleware.MethodAndPathSkipper(http.MethodGet, match("^/api/v2.0/ping"))
|
||||
|
||||
// dbTxSkippers skip the transaction middleware for GET Blob, PATCH Blob Upload and PUT Blob Upload APIs
|
||||
// because the APIs may take a long time to run, enable the transaction middleware in them will hold the database connections
|
||||
// until the API finished, this behavior may eat all the database connections.
|
||||
@ -46,6 +50,7 @@ var (
|
||||
middleware.MethodAndPathSkipper(http.MethodGet, distribution.BlobURLRegexp),
|
||||
middleware.MethodAndPathSkipper(http.MethodPatch, distribution.BlobUploadURLRegexp),
|
||||
middleware.MethodAndPathSkipper(http.MethodPut, distribution.BlobUploadURLRegexp),
|
||||
pingSkipper,
|
||||
}
|
||||
|
||||
// readonlySkippers skip the post request when harbor sets to readonly.
|
||||
@ -62,6 +67,7 @@ var (
|
||||
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/retention/task/"+numericRegexp.String())),
|
||||
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/schedules/"+numericRegexp.String())),
|
||||
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/webhook/"+numericRegexp.String())),
|
||||
pingSkipper,
|
||||
}
|
||||
)
|
||||
|
||||
@ -72,11 +78,12 @@ func MiddleWares() []beego.MiddleWare {
|
||||
log.Middleware(),
|
||||
session.Middleware(),
|
||||
csrf.Middleware(),
|
||||
orm.Middleware(),
|
||||
notification.Middleware(), // notification must ahead of transaction ensure the DB transaction execution complete
|
||||
orm.Middleware(pingSkipper),
|
||||
notification.Middleware(pingSkipper), // notification must ahead of transaction ensure the DB transaction execution complete
|
||||
transaction.Middleware(dbTxSkippers...),
|
||||
artifactinfo.Middleware(),
|
||||
security.Middleware(),
|
||||
security.Middleware(pingSkipper),
|
||||
security.UnauthorizedMiddleware(),
|
||||
readonly.Middleware(readonlySkippers...),
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/server/middleware"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -34,7 +35,6 @@ var (
|
||||
&basicAuth{},
|
||||
&session{},
|
||||
&proxyCacheSecret{},
|
||||
&unauthorized{},
|
||||
}
|
||||
)
|
||||
|
||||
@ -44,23 +44,34 @@ type generator interface {
|
||||
}
|
||||
|
||||
// Middleware returns a security context middleware that populates the security context into the request context
|
||||
func Middleware() func(http.Handler) http.Handler {
|
||||
return func(handler http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log := log.G(r.Context())
|
||||
mode, err := config.AuthMode()
|
||||
if err == nil {
|
||||
r = r.WithContext(lib.WithAuthMode(r.Context(), mode))
|
||||
} else {
|
||||
log.Warningf("failed to get auth mode: %v", err)
|
||||
func Middleware(skippers ...middleware.Skipper) func(http.Handler) http.Handler {
|
||||
return middleware.New(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
log := log.G(r.Context())
|
||||
mode, err := config.AuthMode()
|
||||
if err == nil {
|
||||
r = r.WithContext(lib.WithAuthMode(r.Context(), mode))
|
||||
} else {
|
||||
log.Warningf("failed to get auth mode: %v", err)
|
||||
}
|
||||
for _, generator := range generators {
|
||||
if ctx := generator.Generate(r); ctx != nil {
|
||||
r = r.WithContext(security.NewContext(r.Context(), ctx))
|
||||
break
|
||||
}
|
||||
for _, generator := range generators {
|
||||
if ctx := generator.Generate(r); ctx != nil {
|
||||
r = r.WithContext(security.NewContext(r.Context(), ctx))
|
||||
break
|
||||
}
|
||||
}
|
||||
handler.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
}, skippers...)
|
||||
}
|
||||
|
||||
// UnauthorizedMiddleware returns a security context middleware
|
||||
// that populates the unauthorized security context when not security context found in the request context
|
||||
func UnauthorizedMiddleware(skippers ...middleware.Skipper) func(http.Handler) http.Handler {
|
||||
return middleware.New(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
if _, ok := security.FromContext(r.Context()); !ok {
|
||||
u := &unauthorized{}
|
||||
r = r.WithContext(security.NewContext(r.Context(), u.Generate(r)))
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
}, skippers...)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user