diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 14:59:07 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 14:59:07 +0300 |
commit | 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch) | |
tree | 544930fb309b30317ae9797a9683768705d664c4 /workhorse/internal/proxy | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'workhorse/internal/proxy')
-rw-r--r-- | workhorse/internal/proxy/proxy.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/workhorse/internal/proxy/proxy.go b/workhorse/internal/proxy/proxy.go new file mode 100644 index 00000000000..1bc417a841f --- /dev/null +++ b/workhorse/internal/proxy/proxy.go @@ -0,0 +1,62 @@ +package proxy + +import ( + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "time" + + "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper" +) + +var ( + defaultTarget = helper.URLMustParse("http://localhost") +) + +type Proxy struct { + Version string + reverseProxy *httputil.ReverseProxy + AllowResponseBuffering bool +} + +func NewProxy(myURL *url.URL, version string, roundTripper http.RoundTripper) *Proxy { + p := Proxy{Version: version, AllowResponseBuffering: true} + + if myURL == nil { + myURL = defaultTarget + } + + u := *myURL // Make a copy of p.URL + u.Path = "" + p.reverseProxy = httputil.NewSingleHostReverseProxy(&u) + p.reverseProxy.Transport = roundTripper + return &p +} + +func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Clone request + req := *r + req.Header = helper.HeaderClone(r.Header) + + // Set Workhorse version + req.Header.Set("Gitlab-Workhorse", p.Version) + req.Header.Set("Gitlab-Workhorse-Proxy-Start", fmt.Sprintf("%d", time.Now().UnixNano())) + + if p.AllowResponseBuffering { + helper.AllowResponseBuffering(w) + } + + // If the ultimate client disconnects when the response isn't fully written + // to them yet, httputil.ReverseProxy panics with a net/http.ErrAbortHandler + // error. We can catch and discard this to keep the error log clean + defer func() { + if err := recover(); err != nil { + if err != http.ErrAbortHandler { + panic(err) + } + } + }() + + p.reverseProxy.ServeHTTP(w, &req) +} |