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/api/block.go | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'workhorse/internal/api/block.go')
-rw-r--r-- | workhorse/internal/api/block.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/workhorse/internal/api/block.go b/workhorse/internal/api/block.go new file mode 100644 index 00000000000..92322906c03 --- /dev/null +++ b/workhorse/internal/api/block.go @@ -0,0 +1,61 @@ +package api + +import ( + "fmt" + "net/http" + + "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper" +) + +// Prevent internal API responses intended for gitlab-workhorse from +// leaking to the end user +func Block(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rw := &blocker{rw: w, r: r} + defer rw.flush() + h.ServeHTTP(rw, r) + }) +} + +type blocker struct { + rw http.ResponseWriter + r *http.Request + hijacked bool + status int +} + +func (b *blocker) Header() http.Header { + return b.rw.Header() +} + +func (b *blocker) Write(data []byte) (int, error) { + if b.status == 0 { + b.WriteHeader(http.StatusOK) + } + if b.hijacked { + return len(data), nil + } + + return b.rw.Write(data) +} + +func (b *blocker) WriteHeader(status int) { + if b.status != 0 { + return + } + + if helper.IsContentType(ResponseContentType, b.Header().Get("Content-Type")) { + b.status = 500 + b.Header().Del("Content-Length") + b.hijacked = true + helper.Fail500(b.rw, b.r, fmt.Errorf("api.blocker: forbidden content-type: %q", ResponseContentType)) + return + } + + b.status = status + b.rw.WriteHeader(b.status) +} + +func (b *blocker) flush() { + b.WriteHeader(http.StatusOK) +} |