mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-28 03:27:41 +01:00
Merge pull request #13422 from heww/disable-db-acess-for-ping
feat: skip middlewares require db for ping
This commit is contained in:
commit
955431257c
@ -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)
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,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.
|
||||
@ -47,6 +51,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.
|
||||
@ -63,6 +68,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,
|
||||
}
|
||||
)
|
||||
|
||||
@ -74,11 +80,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