Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfeistel <6742251-feistel@users.noreply.gitlab.com>2022-05-22 17:02:51 +0300
committerfeistel <6742251-feistel@users.noreply.gitlab.com>2022-05-22 17:02:51 +0300
commitf8d62fd4de797a64734f08f09f57bd2271b740c7 (patch)
tree83bea64ba87773f9299ff1057ee911f70862e52c
parenta80c58682c3c313f52deecdebecfef2d1f7e3b21 (diff)
Reduce lookup path requests in the handler pipeline
-rw-r--r--app.go59
-rw-r--r--internal/auth/middleware.go47
2 files changed, 46 insertions, 60 deletions
diff --git a/app.go b/app.go
index 2fa100fe..f55993f3 100644
--- a/app.go
+++ b/app.go
@@ -87,68 +87,10 @@ func (a *theApp) getTLSConfig() (*cryptotls.Config, error) {
return a.tlsConfig, err
}
-func (a *theApp) redirectToHTTPS(w http.ResponseWriter, r *http.Request, statusCode int) {
- u := *r.URL
- u.Scheme = request.SchemeHTTPS
- u.Host = r.Host
- u.User = nil
-
- http.Redirect(w, r, u.String(), statusCode)
-}
-
func (a *theApp) domain(ctx context.Context, host string) (*domain.Domain, error) {
return a.source.GetDomain(ctx, host)
}
-// checkAuthAndServeNotFound performs the auth process if domain can't be found
-// the main purpose of this process is to avoid leaking the project existence/not-existence
-// by behaving the same if user has no access to the project or if project simply does not exists
-func (a *theApp) checkAuthAndServeNotFound(domain *domain.Domain, w http.ResponseWriter, r *http.Request) {
- // To avoid user knowing if pages exist, we will force user to login and authorize pages
- if a.Auth.CheckAuthenticationWithoutProject(w, r, domain) {
- return
- }
-
- // auth succeeded try to serve the correct 404 page
- domain.ServeNotFoundAuthFailed(w, r)
-}
-
-func (a *theApp) tryAuxiliaryHandlers(w http.ResponseWriter, r *http.Request, https bool, domain *domain.Domain) bool {
- if _, err := domain.GetLookupPath(r); err != nil {
- if errors.Is(err, gitlab.ErrDiskDisabled) {
- errortracking.CaptureErrWithReqAndStackTrace(err, r)
- httperrors.Serve500(w)
- return true
- }
-
- // redirect to auth and serve not found
- a.checkAuthAndServeNotFound(domain, w, r)
- return true
- }
-
- if !https && domain.IsHTTPSOnly(r) {
- a.redirectToHTTPS(w, r, http.StatusMovedPermanently)
- return true
- }
-
- return false
-}
-
-// auxiliaryMiddleware will handle status updates, not-ready requests and other
-// not static-content responses
-func (a *theApp) auxiliaryMiddleware(handler http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- domain := domain.FromRequest(r)
- https := request.IsHTTPS(r)
-
- if a.tryAuxiliaryHandlers(w, r, https, domain) {
- return
- }
-
- handler.ServeHTTP(w, r)
- })
-}
-
// serveFileOrNotFoundHandler will serve static content or
// return a 404 Not Found response
func (a *theApp) serveFileOrNotFoundHandler() http.Handler {
@@ -202,7 +144,6 @@ func (a *theApp) buildHandlerPipeline() (http.Handler, error) {
handler = corsHandler.Handler(handler)
}
handler = a.Auth.AuthorizationMiddleware(handler)
- handler = a.auxiliaryMiddleware(handler)
handler = handlers.ArtifactMiddleware(handler, a.Handlers)
handler = a.Auth.AuthenticationMiddleware(handler, a.source)
handler = a.AcmeMiddleware.AcmeMiddleware(handler)
diff --git a/internal/auth/middleware.go b/internal/auth/middleware.go
index 23ea0cf3..f9800b95 100644
--- a/internal/auth/middleware.go
+++ b/internal/auth/middleware.go
@@ -1,10 +1,15 @@
package auth
import (
+ "errors"
"net/http"
domainCfg "gitlab.com/gitlab-org/gitlab-pages/internal/domain"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/errortracking"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/request"
"gitlab.com/gitlab-org/gitlab-pages/internal/source"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab"
)
// AuthenticationMiddleware handles authentication requests
@@ -22,9 +27,27 @@ func (a *Auth) AuthenticationMiddleware(handler http.Handler, s source.Source) h
func (a *Auth) AuthorizationMiddleware(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
domain := domainCfg.FromRequest(r)
+ lp, err := domain.GetLookupPath(r)
+
+ if err != nil {
+ if errors.Is(err, gitlab.ErrDiskDisabled) {
+ errortracking.CaptureErrWithReqAndStackTrace(err, r)
+ httperrors.Serve500(w)
+ return
+ }
+
+ // redirect to auth and serve not found
+ a.checkAuthAndServeNotFound(domain, w, r)
+ return
+ }
+
+ if lp.IsHTTPSOnly && !request.IsHTTPS(r) {
+ redirectToHTTPS(w, r, http.StatusMovedPermanently)
+ return
+ }
// Only for projects that have access control enabled
- if domain.IsAccessControlEnabled(r) {
+ if lp.HasAccessControl {
// accessControlMiddleware
if a.CheckAuthentication(w, r, domain) {
return
@@ -34,3 +57,25 @@ func (a *Auth) AuthorizationMiddleware(handler http.Handler) http.Handler {
handler.ServeHTTP(w, r)
})
}
+
+// checkAuthAndServeNotFound performs the auth process if domain can't be found
+// the main purpose of this process is to avoid leaking the project existence/not-existence
+// by behaving the same if user has no access to the project or if project simply does not exists
+func (a *Auth) checkAuthAndServeNotFound(domain *domainCfg.Domain, w http.ResponseWriter, r *http.Request) {
+ // To avoid user knowing if pages exist, we will force user to login and authorize pages
+ if a.CheckAuthenticationWithoutProject(w, r, domain) {
+ return
+ }
+
+ // auth succeeded try to serve the correct 404 page
+ domain.ServeNotFoundAuthFailed(w, r)
+}
+
+func redirectToHTTPS(w http.ResponseWriter, r *http.Request, statusCode int) {
+ u := *r.URL
+ u.Scheme = request.SchemeHTTPS
+ u.Host = r.Host
+ u.User = nil
+
+ http.Redirect(w, r, u.String(), statusCode)
+}