diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go index a193ed901..6e147d76f 100644 --- a/modules/httplib/serve.go +++ b/modules/httplib/serve.go @@ -17,11 +17,14 @@ import ( "time" charsetModule "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" + + "github.com/klauspost/compress/gzhttp" ) type ServeHeaderOptions struct { @@ -38,6 +41,11 @@ type ServeHeaderOptions struct { func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) { header := w.Header() + skipCompressionExts := container.SetOf(".gz", ".bz2", ".zip", ".xz", ".zst", ".deb", ".apk", ".jar", ".png", ".jpg", ".webp") + if skipCompressionExts.Contains(strings.ToLower(path.Ext(opts.Filename))) { + w.Header().Add(gzhttp.HeaderNoCompression, "1") + } + contentType := typesniffer.ApplicationOctetStream if opts.ContentType != "" { if opts.ContentTypeCharset != "" { diff --git a/tests/integration/repo_archive_test.go b/tests/integration/repo_archive_test.go new file mode 100644 index 000000000..ebc646737 --- /dev/null +++ b/tests/integration/repo_archive_test.go @@ -0,0 +1,31 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "io" + "net/http" + "testing" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/routers" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestRepoDownloadArchive(t *testing.T) { + defer tests.PrepareTestEnv(t)() + defer test.MockVariableValue(&setting.EnableGzip, true)() + defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() + + req := NewRequest(t, "GET", "/user2/repo1/archive/master.zip") + req.Header.Set("Accept-Encoding", "gzip") + resp := MakeRequest(t, req, http.StatusOK) + bs, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Empty(t, resp.Header().Get("Content-Encoding")) + assert.Equal(t, 320, len(bs)) +}