diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 13:37:47 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 13:37:47 +0000 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /workhorse | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) | |
download | gitlab-ce-aee0a117a889461ce8ced6fcf73207fe017f1d99.tar.gz |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'workhorse')
22 files changed, 158 insertions, 40 deletions
diff --git a/workhorse/.tool-versions b/workhorse/.tool-versions index 9d3b3b30ff2..bf23029f784 100644 --- a/workhorse/.tool-versions +++ b/workhorse/.tool-versions @@ -1 +1 @@ -golang 1.16.9 +golang 1.16.12 diff --git a/workhorse/cmd/gitlab-zip-cat/main.go b/workhorse/cmd/gitlab-zip-cat/main.go index 12a4187bad1..05170ba5994 100644 --- a/workhorse/cmd/gitlab-zip-cat/main.go +++ b/workhorse/cmd/gitlab-zip-cat/main.go @@ -1,7 +1,6 @@ package main import ( - "archive/zip" "context" "errors" "flag" @@ -9,6 +8,7 @@ import ( "io" "os" + zip "gitlab.com/gitlab-org/golang-archive-zip" "gitlab.com/gitlab-org/labkit/mask" "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts" diff --git a/workhorse/go.mod b/workhorse/go.mod index 1d9ae69289c..9fb4c25166b 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -29,6 +29,7 @@ require ( github.com/smartystreets/goconvey v1.6.4 github.com/stretchr/testify v1.7.0 gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74 + gitlab.com/gitlab-org/golang-archive-zip v0.1.1 gitlab.com/gitlab-org/labkit v1.6.0 gocloud.dev v0.23.0 golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 diff --git a/workhorse/go.sum b/workhorse/go.sum index c5bcf1571be..76590474a00 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -835,6 +835,8 @@ gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74 h1:7R gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74/go.mod h1:2McjFiZrwflPGtXSquCAXWzewmxTPytoI/vamNz/QPM= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U= gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc= +gitlab.com/gitlab-org/golang-archive-zip v0.1.1 h1:35k9giivbxwF03+8A05Cm8YoxoakU8FBCj5gysjCTCE= +gitlab.com/gitlab-org/golang-archive-zip v0.1.1/go.mod h1:ZDtqpWPGPB9qBuZnZDrKQjIdJtkN7ZAoVwhT6H2o2kE= gitlab.com/gitlab-org/labkit v0.0.0-20190221122536-0c3fc7cdd57c/go.mod h1:rYhLgfrbEcyfinG+R3EvKu6bZSsmwQqcXzLfHWSfUKM= gitlab.com/gitlab-org/labkit v0.0.0-20200908084045-45895e129029/go.mod h1:SNfxkfUwVNECgtmluVayv0GWFgEjjBs5AzgsowPQuo0= gitlab.com/gitlab-org/labkit v1.0.0/go.mod h1:nohrYTSLDnZix0ebXZrbZJjymRar8HeV2roWL5/jw2U= diff --git a/workhorse/internal/api/api_test.go b/workhorse/internal/api/api_test.go index 43e3604cc9c..b82bb55fb85 100644 --- a/workhorse/internal/api/api_test.go +++ b/workhorse/internal/api/api_test.go @@ -49,7 +49,7 @@ func getGeoProxyURLGivenResponse(t *testing.T, givenInternalApiResponse string) } func testRailsServer(url *regexp.Regexp, code int, body string) *httptest.Server { - return testhelper.TestServerWithHandler(url, func(w http.ResponseWriter, r *http.Request) { + return testhelper.TestServerWithHandlerWithGeoPolling(url, func(w http.ResponseWriter, r *http.Request) { // return a 204 No Content response if we don't receive the JWT header if r.Header.Get(secret.RequestHeader) == "" { w.WriteHeader(204) diff --git a/workhorse/internal/artifacts/artifacts_upload_test.go b/workhorse/internal/artifacts/artifacts_upload_test.go index df1c30dcff0..3e8a52be1a1 100644 --- a/workhorse/internal/artifacts/artifacts_upload_test.go +++ b/workhorse/internal/artifacts/artifacts_upload_test.go @@ -270,7 +270,7 @@ func TestUploadHandlerForMultipleFiles(t *testing.T) { require.NoError(t, s.writer.Close()) response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer) - require.Equal(t, http.StatusBadRequest, response.Code) + require.Equal(t, http.StatusInternalServerError, response.Code) } func TestUploadFormProcessing(t *testing.T) { diff --git a/workhorse/internal/testhelper/testhelper.go b/workhorse/internal/testhelper/testhelper.go index 7e66563e438..dae8f9b3149 100644 --- a/workhorse/internal/testhelper/testhelper.go +++ b/workhorse/internal/testhelper/testhelper.go @@ -22,6 +22,10 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret" ) +const ( + geoProxyEndpointPath = "/api/v4/geo/proxy" +) + func ConfigureSecret() { secret.SetPath(path.Join(RootDir(), "testdata/test-secret")) } @@ -50,7 +54,20 @@ func RequireResponseHeader(t *testing.T, w interface{}, header string, expected require.Equal(t, expected, actual, "values for HTTP header %s", header) } +// TestServerWithHandler skips Geo API polling for a proxy URL by default, +// use TestServerWithHandlerWithGeoPolling if you need to explicitly +// handle Geo API polling request as well. func TestServerWithHandler(url *regexp.Regexp, handler http.HandlerFunc) *httptest.Server { + return TestServerWithHandlerWithGeoPolling(url, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == geoProxyEndpointPath { + return + } + + handler(w, r) + })) +} + +func TestServerWithHandlerWithGeoPolling(url *regexp.Regexp, handler http.HandlerFunc) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { logEntry := log.WithFields(log.Fields{ "method": r.Method, diff --git a/workhorse/internal/upload/rewrite.go b/workhorse/internal/upload/rewrite.go index 3dfab120188..b9324ac8b7b 100644 --- a/workhorse/internal/upload/rewrite.go +++ b/workhorse/internal/upload/rewrite.go @@ -24,10 +24,12 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif" ) +const maxFilesAllowed = 10 + // ErrInjectedClientParam means that the client sent a parameter that overrides one of our own fields var ( - ErrInjectedClientParam = errors.New("injected client parameter") - ErrMultipleFilesUploaded = errors.New("upload request contains more than one file") + ErrInjectedClientParam = errors.New("injected client parameter") + ErrTooManyFilesUploaded = fmt.Errorf("upload request contains more than %v files", maxFilesAllowed) ) var ( @@ -117,8 +119,8 @@ func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, pr } func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipart.Part, opts *filestore.SaveFileOpts) error { - if rew.filter.Count() > 0 { - return ErrMultipleFilesUploaded + if rew.filter.Count() >= maxFilesAllowed { + return ErrTooManyFilesUploaded } multipartFiles.WithLabelValues(rew.filter.Name()).Inc() diff --git a/workhorse/internal/upload/saved_file_tracker.go b/workhorse/internal/upload/saved_file_tracker.go index cd41e661b7d..e6f9a8c9a88 100644 --- a/workhorse/internal/upload/saved_file_tracker.go +++ b/workhorse/internal/upload/saved_file_tracker.go @@ -27,6 +27,10 @@ func (s *SavedFileTracker) Count() int { } func (s *SavedFileTracker) ProcessFile(_ context.Context, fieldName string, file *filestore.FileHandler, _ *multipart.Writer) error { + if _, ok := s.rewrittenFields[fieldName]; ok { + return fmt.Errorf("the %v field has already been processed", fieldName) + } + s.Track(fieldName, file.LocalPath) return nil } diff --git a/workhorse/internal/upload/saved_file_tracker_test.go b/workhorse/internal/upload/saved_file_tracker_test.go index b34dd9aed4f..ba927db253e 100644 --- a/workhorse/internal/upload/saved_file_tracker_test.go +++ b/workhorse/internal/upload/saved_file_tracker_test.go @@ -37,3 +37,14 @@ func TestSavedFileTracking(t *testing.T) { require.Contains(t, rewrittenFields, "test") } + +func TestDuplicatedFileProcessing(t *testing.T) { + tracker := SavedFileTracker{} + file := &filestore.FileHandler{} + + require.NoError(t, tracker.ProcessFile(context.Background(), "file", file, nil)) + + err := tracker.ProcessFile(context.Background(), "file", file, nil) + require.Error(t, err) + require.Equal(t, "the file field has already been processed", err.Error()) +} diff --git a/workhorse/internal/upload/uploads.go b/workhorse/internal/upload/uploads.go index 8f4c8bb95f0..b408d260379 100644 --- a/workhorse/internal/upload/uploads.go +++ b/workhorse/internal/upload/uploads.go @@ -35,8 +35,8 @@ func HandleFileUploads(w http.ResponseWriter, r *http.Request, h http.Handler, p switch err { case ErrInjectedClientParam: helper.CaptureAndFail(w, r, err, "Bad Request", http.StatusBadRequest) - case ErrMultipleFilesUploaded: - helper.CaptureAndFail(w, r, err, "Uploading multiple files is not allowed", http.StatusBadRequest) + case ErrTooManyFilesUploaded: + helper.CaptureAndFail(w, r, err, err.Error(), http.StatusBadRequest) case http.ErrNotMultipart: h.ServeHTTP(w, r) case filestore.ErrEntityTooLarge: diff --git a/workhorse/internal/upload/uploads_test.go b/workhorse/internal/upload/uploads_test.go index b5db8003d41..7c22b3b4e28 100644 --- a/workhorse/internal/upload/uploads_test.go +++ b/workhorse/internal/upload/uploads_test.go @@ -260,10 +260,10 @@ func TestUploadingMultipleFiles(t *testing.T) { var buffer bytes.Buffer writer := multipart.NewWriter(&buffer) - _, err = writer.CreateFormFile("file", "my.file") - require.NoError(t, err) - _, err = writer.CreateFormFile("file", "my.file") - require.NoError(t, err) + for i := 0; i < 11; i++ { + _, err = writer.CreateFormFile(fmt.Sprintf("file %v", i), "my.file") + require.NoError(t, err) + } require.NoError(t, writer.Close()) httpRequest, err := http.NewRequest("PUT", "/url/path", &buffer) @@ -279,7 +279,7 @@ func TestUploadingMultipleFiles(t *testing.T) { HandleFileUploads(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts) require.Equal(t, 400, response.Code) - require.Equal(t, "Uploading multiple files is not allowed\n", response.Body.String()) + require.Equal(t, "upload request contains more than 10 files\n", response.Body.String()) } func TestUploadProcessingFile(t *testing.T) { diff --git a/workhorse/internal/upstream/metrics.go b/workhorse/internal/upstream/metrics.go index 38528056d43..1a11bdc8b53 100644 --- a/workhorse/internal/upstream/metrics.go +++ b/workhorse/internal/upstream/metrics.go @@ -101,6 +101,16 @@ var ( }, []string{"code", "method", "route"}, ) + + httpGeoProxiedRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: httpSubsystem, + Name: "geo_proxied_requests_total", + Help: "A counter for Geo proxied requests through workhorse.", + }, + []string{"code", "method", "route"}, + ) ) func instrumentRoute(next http.Handler, method string, regexpStr string) http.Handler { @@ -115,3 +125,7 @@ func instrumentRoute(next http.Handler, method string, regexpStr string) http.Ha return handler } + +func instrumentGeoProxyRoute(next http.Handler, method string, regexpStr string) http.Handler { + return promhttp.InstrumentHandlerCounter(httpGeoProxiedRequestsTotal.MustCurryWith(map[string]string{"route": regexpStr}), next) +} diff --git a/workhorse/internal/upstream/metrics_test.go b/workhorse/internal/upstream/metrics_test.go new file mode 100644 index 00000000000..29a9e09777c --- /dev/null +++ b/workhorse/internal/upstream/metrics_test.go @@ -0,0 +1,54 @@ +package upstream + +import ( + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab/workhorse/internal/config" +) + +func TestInstrumentGeoProxyRoute(t *testing.T) { + const ( + remote = `\A/remote\z` + local = `\A/local\z` + main = "" + ) + + u := newUpstream(config.Config{}, logrus.StandardLogger(), func(u *upstream) { + u.Routes = []routeEntry{ + handleRouteWithMatchers(u, remote, withGeoProxy()), + handleRouteWithMatchers(u, local), + handleRouteWithMatchers(u, main), + } + }) + ts := httptest.NewServer(u) + defer ts.Close() + + testCases := []testCase{ + {"remote", "/remote", remote}, + {"local", "/local", local}, + {"main", "/", main}, + } + + httpGeoProxiedRequestsTotal.Reset() + + runTestCases(t, ts, testCases) + + require.Equal(t, 1, testutil.CollectAndCount(httpGeoProxiedRequestsTotal)) + require.InDelta(t, 1, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", remote)), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", local)), 0.1) + require.InDelta(t, 0, testutil.ToFloat64(httpGeoProxiedRequestsTotal.WithLabelValues("200", "get", main)), 0.1) +} + +func handleRouteWithMatchers(u *upstream, regex string, matchers ...func(*routeOptions)) routeEntry { + handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + io.WriteString(w, regex) + }) + return u.route("", regex, handler, matchers...) +} diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go index 22b30fe8a63..06160702f84 100644 --- a/workhorse/internal/upstream/routes.go +++ b/workhorse/internal/upstream/routes.go @@ -42,8 +42,9 @@ type routeEntry struct { } type routeOptions struct { - tracing bool - matchers []matcherFunc + tracing bool + isGeoProxyRoute bool + matchers []matcherFunc } type uploadPreparers struct { @@ -94,7 +95,13 @@ func withoutTracing() func(*routeOptions) { } } -func (u *upstream) observabilityMiddlewares(handler http.Handler, method string, regexpStr string) http.Handler { +func withGeoProxy() func(*routeOptions) { + return func(options *routeOptions) { + options.isGeoProxyRoute = true + } +} + +func (u *upstream) observabilityMiddlewares(handler http.Handler, method string, regexpStr string, opts *routeOptions) http.Handler { handler = log.AccessLogger( handler, log.WithAccessLogger(u.accessLogger), @@ -106,6 +113,11 @@ func (u *upstream) observabilityMiddlewares(handler http.Handler, method string, ) handler = instrumentRoute(handler, method, regexpStr) // Add prometheus metrics + + if opts != nil && opts.isGeoProxyRoute { + handler = instrumentGeoProxyRoute(handler, method, regexpStr) // Add Geo prometheus metrics + } + return handler } @@ -119,7 +131,7 @@ func (u *upstream) route(method, regexpStr string, handler http.Handler, opts .. f(&options) } - handler = u.observabilityMiddlewares(handler, method, regexpStr) + handler = u.observabilityMiddlewares(handler, method, regexpStr, &options) handler = denyWebsocket(handler) // Disallow websockets if options.tracing { // Add distributed tracing @@ -136,7 +148,7 @@ func (u *upstream) route(method, regexpStr string, handler http.Handler, opts .. func (u *upstream) wsRoute(regexpStr string, handler http.Handler, matchers ...matcherFunc) routeEntry { method := "GET" - handler = u.observabilityMiddlewares(handler, method, regexpStr) + handler = u.observabilityMiddlewares(handler, method, regexpStr, nil) return routeEntry{ method: method, diff --git a/workhorse/internal/upstream/upstream.go b/workhorse/internal/upstream/upstream.go index e57f58d59dd..065cae53e2b 100644 --- a/workhorse/internal/upstream/upstream.go +++ b/workhorse/internal/upstream/upstream.go @@ -65,7 +65,7 @@ func newUpstream(cfg config.Config, accessLogger *logrus.Logger, routesCallback Config: cfg, accessLogger: accessLogger, // Kind of a feature flag. See https://gitlab.com/groups/gitlab-org/-/epics/5914#note_564974130 - enableGeoProxyFeature: os.Getenv("GEO_SECONDARY_PROXY") == "1", + enableGeoProxyFeature: os.Getenv("GEO_SECONDARY_PROXY") != "0", geoProxyBackend: &url.URL{}, } if up.geoProxyPollSleep == nil { @@ -239,5 +239,5 @@ func (u *upstream) updateGeoProxyFields(geoProxyURL *url.URL) { geoProxyRoundTripper := roundtripper.NewBackendRoundTripper(u.geoProxyBackend, "", u.ProxyHeadersTimeout, u.DevelopmentMode) geoProxyUpstream := proxypkg.NewProxy(u.geoProxyBackend, u.Version, geoProxyRoundTripper) u.geoProxyCableRoute = u.wsRoute(`^/-/cable\z`, geoProxyUpstream) - u.geoProxyRoute = u.route("", "", geoProxyUpstream) + u.geoProxyRoute = u.route("", "", geoProxyUpstream, withGeoProxy()) } diff --git a/workhorse/internal/upstream/upstream_test.go b/workhorse/internal/upstream/upstream_test.go index 53c15bb7e91..2031fa84ce2 100644 --- a/workhorse/internal/upstream/upstream_test.go +++ b/workhorse/internal/upstream/upstream_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "testing" "time" @@ -28,6 +29,14 @@ type testCase struct { expectedResponse string } +func TestMain(m *testing.M) { + // Secret should be configured before any Geo API poll happens to prevent + // race conditions where the first API call happens without a secret path + testhelper.ConfigureSecret() + + os.Exit(m.Run()) +} + func TestRouting(t *testing.T) { handle := func(u *upstream, regex string) routeEntry { handler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { @@ -288,11 +297,6 @@ func startWorkhorseServer(railsServerURL string, enableGeoProxyFeature bool) (*h } cfg := newUpstreamConfig(railsServerURL) upstreamHandler := newUpstream(*cfg, logrus.StandardLogger(), myConfigureRoutes) - - // Secret should be configured before the first Geo API poll happens on server start - // to prevent race conditions where the first API call happens without a secret path - testhelper.ConfigureSecret() - ws := httptest.NewServer(upstreamHandler) waitForNextApiPoll := func() {} diff --git a/workhorse/internal/zipartifacts/metadata.go b/workhorse/internal/zipartifacts/metadata.go index 1ecf52deafb..456d2c101cb 100644 --- a/workhorse/internal/zipartifacts/metadata.go +++ b/workhorse/internal/zipartifacts/metadata.go @@ -1,7 +1,6 @@ package zipartifacts import ( - "archive/zip" "compress/gzip" "encoding/binary" "encoding/json" @@ -9,6 +8,8 @@ import ( "path" "sort" "strconv" + + zip "gitlab.com/gitlab-org/golang-archive-zip" ) type metadata struct { diff --git a/workhorse/internal/zipartifacts/metadata_test.go b/workhorse/internal/zipartifacts/metadata_test.go index ffc5f58cb21..353ed4376f6 100644 --- a/workhorse/internal/zipartifacts/metadata_test.go +++ b/workhorse/internal/zipartifacts/metadata_test.go @@ -1,7 +1,6 @@ package zipartifacts_test import ( - "archive/zip" "bytes" "compress/gzip" "context" @@ -12,6 +11,7 @@ import ( "testing" "github.com/stretchr/testify/require" + zip "gitlab.com/gitlab-org/golang-archive-zip" "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts" ) diff --git a/workhorse/internal/zipartifacts/open_archive.go b/workhorse/internal/zipartifacts/open_archive.go index ec2fd691038..881ef915d75 100644 --- a/workhorse/internal/zipartifacts/open_archive.go +++ b/workhorse/internal/zipartifacts/open_archive.go @@ -1,7 +1,6 @@ package zipartifacts import ( - "archive/zip" "context" "fmt" "io" @@ -12,6 +11,7 @@ import ( "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport" "gitlab.com/gitlab-org/gitlab/workhorse/internal/httprs" + zip "gitlab.com/gitlab-org/golang-archive-zip" "gitlab.com/gitlab-org/labkit/mask" ) diff --git a/workhorse/internal/zipartifacts/open_archive_test.go b/workhorse/internal/zipartifacts/open_archive_test.go index ea1fc606784..e339454345b 100644 --- a/workhorse/internal/zipartifacts/open_archive_test.go +++ b/workhorse/internal/zipartifacts/open_archive_test.go @@ -1,7 +1,6 @@ package zipartifacts import ( - "archive/zip" "bytes" "context" "fmt" @@ -10,11 +9,10 @@ import ( "net/http/httptest" "os" "path/filepath" - "runtime" - "strings" "testing" "github.com/stretchr/testify/require" + zip "gitlab.com/gitlab-org/golang-archive-zip" ) func createArchive(t *testing.T, dir string) (map[string][]byte, int64) { @@ -73,10 +71,6 @@ func TestOpenHTTPArchive(t *testing.T) { } func TestMinimalRangeRequests(t *testing.T) { - if strings.HasPrefix(runtime.Version(), "go1.17") { - t.Skipf("skipped for go1.17: https://gitlab.com/gitlab-org/gitlab/-/issues/340778") - } - dir := t.TempDir() entries, archiveSize := createArchive(t, dir) diff --git a/workhorse/sendfile_test.go b/workhorse/sendfile_test.go index 2408f4fde38..0a01e410d39 100644 --- a/workhorse/sendfile_test.go +++ b/workhorse/sendfile_test.go @@ -5,13 +5,15 @@ import ( "io/ioutil" "mime" "net/http" - "net/http/httptest" "os" "path" + "regexp" "testing" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper" ) func TestDeniedLfsDownload(t *testing.T) { @@ -35,7 +37,7 @@ func allowedXSendfileDownload(t *testing.T, contentFilename string, filePath str prepareDownloadDir(t) // Prepare test server and backend - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.WithFields(log.Fields{"method": r.Method, "url": r.URL}).Info("UPSTREAM") require.Equal(t, "X-Sendfile", r.Header.Get("X-Sendfile-Type")) @@ -69,7 +71,7 @@ func deniedXSendfileDownload(t *testing.T, contentFilename string, filePath stri prepareDownloadDir(t) // Prepare test server and backend - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.WithFields(log.Fields{"method": r.Method, "url": r.URL}).Info("UPSTREAM") require.Equal(t, "X-Sendfile", r.Header.Get("X-Sendfile-Type")) |