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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 14:59:07 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 14:59:07 +0300
commit8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch)
tree544930fb309b30317ae9797a9683768705d664c4 /workhorse/internal/upstream/upstream.go
parent4b1de649d0168371549608993deac953eb692019 (diff)
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'workhorse/internal/upstream/upstream.go')
-rw-r--r--workhorse/internal/upstream/upstream.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/workhorse/internal/upstream/upstream.go b/workhorse/internal/upstream/upstream.go
new file mode 100644
index 00000000000..fd3f6191a5a
--- /dev/null
+++ b/workhorse/internal/upstream/upstream.go
@@ -0,0 +1,123 @@
+/*
+The upstream type implements http.Handler.
+
+In this file we handle request routing and interaction with the authBackend.
+*/
+
+package upstream
+
+import (
+ "fmt"
+
+ "net/http"
+ "strings"
+
+ "github.com/sirupsen/logrus"
+ "gitlab.com/gitlab-org/labkit/correlation"
+
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/config"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/upload"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/upstream/roundtripper"
+ "gitlab.com/gitlab-org/gitlab-workhorse/internal/urlprefix"
+)
+
+var (
+ DefaultBackend = helper.URLMustParse("http://localhost:8080")
+ requestHeaderBlacklist = []string{
+ upload.RewrittenFieldsHeader,
+ }
+)
+
+type upstream struct {
+ config.Config
+ URLPrefix urlprefix.Prefix
+ Routes []routeEntry
+ RoundTripper http.RoundTripper
+ CableRoundTripper http.RoundTripper
+ accessLogger *logrus.Logger
+}
+
+func NewUpstream(cfg config.Config, accessLogger *logrus.Logger) http.Handler {
+ up := upstream{
+ Config: cfg,
+ accessLogger: accessLogger,
+ }
+ if up.Backend == nil {
+ up.Backend = DefaultBackend
+ }
+ if up.CableBackend == nil {
+ up.CableBackend = up.Backend
+ }
+ if up.CableSocket == "" {
+ up.CableSocket = up.Socket
+ }
+ up.RoundTripper = roundtripper.NewBackendRoundTripper(up.Backend, up.Socket, up.ProxyHeadersTimeout, cfg.DevelopmentMode)
+ up.CableRoundTripper = roundtripper.NewBackendRoundTripper(up.CableBackend, up.CableSocket, up.ProxyHeadersTimeout, cfg.DevelopmentMode)
+ up.configureURLPrefix()
+ up.configureRoutes()
+
+ var correlationOpts []correlation.InboundHandlerOption
+ if cfg.PropagateCorrelationID {
+ correlationOpts = append(correlationOpts, correlation.WithPropagation())
+ }
+
+ handler := correlation.InjectCorrelationID(&up, correlationOpts...)
+ return handler
+}
+
+func (u *upstream) configureURLPrefix() {
+ relativeURLRoot := u.Backend.Path
+ if !strings.HasSuffix(relativeURLRoot, "/") {
+ relativeURLRoot += "/"
+ }
+ u.URLPrefix = urlprefix.Prefix(relativeURLRoot)
+}
+
+func (u *upstream) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ helper.FixRemoteAddr(r)
+
+ helper.DisableResponseBuffering(w)
+
+ // Drop RequestURI == "*" (FIXME: why?)
+ if r.RequestURI == "*" {
+ helper.HTTPError(w, r, "Connection upgrade not allowed", http.StatusBadRequest)
+ return
+ }
+
+ // Disallow connect
+ if r.Method == "CONNECT" {
+ helper.HTTPError(w, r, "CONNECT not allowed", http.StatusBadRequest)
+ return
+ }
+
+ // Check URL Root
+ URIPath := urlprefix.CleanURIPath(r.URL.Path)
+ prefix := u.URLPrefix
+ if !prefix.Match(URIPath) {
+ helper.HTTPError(w, r, fmt.Sprintf("Not found %q", URIPath), http.StatusNotFound)
+ return
+ }
+
+ // Look for a matching route
+ var route *routeEntry
+ for _, ro := range u.Routes {
+ if ro.isMatch(prefix.Strip(URIPath), r) {
+ route = &ro
+ break
+ }
+ }
+
+ if route == nil {
+ // The protocol spec in git/Documentation/technical/http-protocol.txt
+ // says we must return 403 if no matching service is found.
+ helper.HTTPError(w, r, "Forbidden", http.StatusForbidden)
+ return
+ }
+
+ for _, h := range requestHeaderBlacklist {
+ r.Header.Del(h)
+ }
+
+ route.handler.ServeHTTP(w, r)
+}