mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-28 19:47:58 +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()
|
mockServer := test.NewJobServiceServer()
|
||||||
defer mockServer.Close()
|
defer mockServer.Close()
|
||||||
|
|
||||||
chain := middleware.Chain(orm.Middleware(), security.Middleware())
|
chain := middleware.Chain(orm.Middleware(), security.Middleware(), security.UnauthorizedMiddleware())
|
||||||
handler = chain(beego.BeeApp.Handlers)
|
handler = chain(beego.BeeApp.Handlers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,10 @@ var (
|
|||||||
match = regexp.MustCompile
|
match = regexp.MustCompile
|
||||||
numericRegexp = match(`[0-9]+`)
|
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
|
// 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
|
// 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.
|
// 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.MethodGet, distribution.BlobURLRegexp),
|
||||||
middleware.MethodAndPathSkipper(http.MethodPatch, distribution.BlobUploadURLRegexp),
|
middleware.MethodAndPathSkipper(http.MethodPatch, distribution.BlobUploadURLRegexp),
|
||||||
middleware.MethodAndPathSkipper(http.MethodPut, distribution.BlobUploadURLRegexp),
|
middleware.MethodAndPathSkipper(http.MethodPut, distribution.BlobUploadURLRegexp),
|
||||||
|
pingSkipper,
|
||||||
}
|
}
|
||||||
|
|
||||||
// readonlySkippers skip the post request when harbor sets to readonly.
|
// 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/retention/task/"+numericRegexp.String())),
|
||||||
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/schedules/"+numericRegexp.String())),
|
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/schedules/"+numericRegexp.String())),
|
||||||
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/webhook/"+numericRegexp.String())),
|
middleware.MethodAndPathSkipper(http.MethodPost, match("^/service/notifications/jobs/webhook/"+numericRegexp.String())),
|
||||||
|
pingSkipper,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -74,11 +80,12 @@ func MiddleWares() []beego.MiddleWare {
|
|||||||
log.Middleware(),
|
log.Middleware(),
|
||||||
session.Middleware(),
|
session.Middleware(),
|
||||||
csrf.Middleware(),
|
csrf.Middleware(),
|
||||||
orm.Middleware(),
|
orm.Middleware(pingSkipper),
|
||||||
notification.Middleware(), // notification must ahead of transaction ensure the DB transaction execution complete
|
notification.Middleware(pingSkipper), // notification must ahead of transaction ensure the DB transaction execution complete
|
||||||
transaction.Middleware(dbTxSkippers...),
|
transaction.Middleware(dbTxSkippers...),
|
||||||
artifactinfo.Middleware(),
|
artifactinfo.Middleware(),
|
||||||
security.Middleware(),
|
security.Middleware(pingSkipper),
|
||||||
|
security.UnauthorizedMiddleware(),
|
||||||
readonly.Middleware(readonlySkippers...),
|
readonly.Middleware(readonlySkippers...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/core/config"
|
"github.com/goharbor/harbor/src/core/config"
|
||||||
"github.com/goharbor/harbor/src/lib"
|
"github.com/goharbor/harbor/src/lib"
|
||||||
"github.com/goharbor/harbor/src/lib/log"
|
"github.com/goharbor/harbor/src/lib/log"
|
||||||
|
"github.com/goharbor/harbor/src/server/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -34,7 +35,6 @@ var (
|
|||||||
&basicAuth{},
|
&basicAuth{},
|
||||||
&session{},
|
&session{},
|
||||||
&proxyCacheSecret{},
|
&proxyCacheSecret{},
|
||||||
&unauthorized{},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,23 +44,34 @@ type generator interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Middleware returns a security context middleware that populates the security context into the request context
|
// Middleware returns a security context middleware that populates the security context into the request context
|
||||||
func Middleware() func(http.Handler) http.Handler {
|
func Middleware(skippers ...middleware.Skipper) func(http.Handler) http.Handler {
|
||||||
return func(handler http.Handler) http.Handler {
|
return middleware.New(func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
log := log.G(r.Context())
|
||||||
log := log.G(r.Context())
|
mode, err := config.AuthMode()
|
||||||
mode, err := config.AuthMode()
|
if err == nil {
|
||||||
if err == nil {
|
r = r.WithContext(lib.WithAuthMode(r.Context(), mode))
|
||||||
r = r.WithContext(lib.WithAuthMode(r.Context(), mode))
|
} else {
|
||||||
} else {
|
log.Warningf("failed to get auth mode: %v", err)
|
||||||
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 {
|
next.ServeHTTP(w, r)
|
||||||
r = r.WithContext(security.NewContext(r.Context(), ctx))
|
}, skippers...)
|
||||||
break
|
}
|
||||||
}
|
|
||||||
}
|
// UnauthorizedMiddleware returns a security context middleware
|
||||||
handler.ServeHTTP(w, r)
|
// 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