mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-15 20:09:18 -05:00
ENABLE_GZIP activated will result in tar.gz & tgz files compressed 2 times in gzip #12897
Closed
opened 2025-11-02 10:24:15 -06:00 by GiteaMirror
·
15 comments
No Branch/Tag Specified
main
release/v1.25
release/v1.24
release/v1.23
release/v1.22
release/v1.21
release/v1.20
release/v1.19
release/v1.18
release/v1.17
release/v1.16
release/v1.15
release/v1.14
release/v1.13
release/v1.12
release/v1.11
release/v1.10
release/v1.9
release/v1.8
v1.25.3
v1.25.2
v1.25.1
v1.25.0
v1.24.7
v1.25.0-rc0
v1.26.0-dev
v1.24.6
v1.24.5
v1.24.4
v1.24.3
v1.24.2
v1.24.1
v1.24.0
v1.23.8
v1.24.0-rc0
v1.25.0-dev
v1.23.7
v1.23.6
v1.23.5
v1.23.4
v1.23.3
v1.23.2
v1.23.1
v1.23.0
v1.23.0-rc0
v1.24.0-dev
v1.22.6
v1.22.5
v1.22.4
v1.22.3
v1.22.2
v1.22.1
v1.22.0
v1.23.0-dev
v1.22.0-rc1
v1.21.11
v1.22.0-rc0
v1.21.10
v1.21.9
v1.21.8
v1.21.7
v1.21.6
v1.21.5
v1.21.4
v1.21.3
v1.21.2
v1.20.6
v1.21.1
v1.21.0
v1.21.0-rc2
v1.21.0-rc1
v1.20.5
v1.22.0-dev
v1.21.0-rc0
v1.20.4
v1.20.3
v1.20.2
v1.20.1
v1.20.0
v1.19.4
v1.21.0-dev
v1.20.0-rc2
v1.20.0-rc1
v1.20.0-rc0
v1.19.3
v1.19.2
v1.19.1
v1.19.0
v1.19.0-rc1
v1.20.0-dev
v1.19.0-rc0
v1.18.5
v1.18.4
v1.18.3
v1.18.2
v1.18.1
v1.18.0
v1.17.4
v1.18.0-rc1
v1.19.0-dev
v1.18.0-rc0
v1.17.3
v1.17.2
v1.17.1
v1.17.0
v1.17.0-rc2
v1.16.9
v1.17.0-rc1
v1.18.0-dev
v1.16.8
v1.16.7
v1.16.6
v1.16.5
v1.16.4
v1.16.3
v1.16.2
v1.16.1
v1.16.0
v1.15.11
v1.17.0-dev
v1.16.0-rc1
v1.15.10
v1.15.9
v1.15.8
v1.15.7
v1.15.6
v1.15.5
v1.15.4
v1.15.3
v1.15.2
v1.15.1
v1.14.7
v1.15.0
v1.15.0-rc3
v1.14.6
v1.15.0-rc2
v1.14.5
v1.16.0-dev
v1.15.0-rc1
v1.14.4
v1.14.3
v1.14.2
v1.14.1
v1.14.0
v1.13.7
v1.14.0-rc2
v1.13.6
v1.13.5
v1.14.0-rc1
v1.15.0-dev
v1.13.4
v1.13.3
v1.13.2
v1.13.1
v1.13.0
v1.12.6
v1.13.0-rc2
v1.14.0-dev
v1.13.0-rc1
v1.12.5
v1.12.4
v1.12.3
v1.12.2
v1.12.1
v1.11.8
v1.12.0
v1.11.7
v1.12.0-rc2
v1.11.6
v1.12.0-rc1
v1.13.0-dev
v1.11.5
v1.11.4
v1.11.3
v1.10.6
v1.12.0-dev
v1.11.2
v1.10.5
v1.11.1
v1.10.4
v1.11.0
v1.11.0-rc2
v1.10.3
v1.11.0-rc1
v1.10.2
v1.10.1
v1.10.0
v1.9.6
v1.9.5
v1.10.0-rc2
v1.11.0-dev
v1.10.0-rc1
v1.9.4
v1.9.3
v1.9.2
v1.9.1
v1.9.0
v1.9.0-rc2
v1.10.0-dev
v1.9.0-rc1
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.8.0-rc3
v1.7.6
v1.8.0-rc2
v1.7.5
v1.8.0-rc1
v1.9.0-dev
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc3
v1.6.4
v1.7.0-rc2
v1.6.3
v1.7.0-rc1
v1.7.0-dev
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc2
v1.5.3
v1.6.0-rc1
v1.6.0-dev
v1.5.2
v1.5.1
v1.5.0
v1.5.0-rc2
v1.5.0-rc1
v1.5.0-dev
v1.4.3
v1.4.2
v1.4.1
v1.4.0
v1.4.0-rc3
v1.4.0-rc2
v1.3.3
v1.4.0-rc1
v1.3.2
v1.3.1
v1.3.0
v1.3.0-rc2
v1.3.0-rc1
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.2.0-rc3
v1.2.0-rc2
v1.1.4
v1.2.0-rc1
v1.1.3
v1.1.2
v1.1.1
v1.1.0
v1.0.2
v1.0.1
v1.0.0
v0.9.99
Labels
Clear labels
$20
$250
$50
$500
backport/done
💎 Bounty
docs-update-needed
good first issue
hacktoberfest
issue/bounty
issue/confirmed
issue/critical
issue/duplicate
issue/needs-feedback
issue/not-a-bug
issue/regression
issue/stale
issue/workaround
lgtm/need 2
modifies/api
modifies/translation
outdated/backport/v1.18
outdated/theme/markdown
outdated/theme/timetracker
performance/bigrepo
performance/cpu
performance/memory
performance/speed
pr/breaking
proposal/accepted
proposal/rejected
pr/wip
pull-request
reviewed/wontfix
💰 Rewarded
skip-changelog
status/blocked
topic/accessibility
topic/api
topic/authentication
topic/build
topic/code-linting
topic/commit-signing
topic/content-rendering
topic/deployment
topic/distribution
topic/federation
topic/gitea-actions
topic/issues
topic/lfs
topic/mobile
topic/moderation
topic/packages
topic/pr
topic/projects
topic/repo
topic/repo-migration
topic/security
topic/theme
topic/ui
topic/ui-interaction
topic/ux
topic/webhooks
topic/wiki
type/bug
type/deprecation
type/docs
type/enhancement
type/feature
type/miscellaneous
type/proposal
type/question
type/refactoring
type/summary
type/testing
type/upstream
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/gitea#12897
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Daryes on GitHub (Apr 22, 2024).
Originally assigned to: @wxiaoguang on GitHub.
Description
Had to dig to understand what happened.
It started with retrieving a git repo in Gitea as an archive and having tar failing on it complaining it is not a tar archive.
Thing is, it was a gzip archive. Then after a gunzip, the .tar file was in fact a ... gzip file too.
Here are the shell commands to demonstrate this, but you can also use 7zip in a file browser, it will show an extra level with the archive name and no extension before having the first directory level.
It went under the radar for a while as I rarely use this mechanism with the Gitea instance.
While digging in the configuration I found that I had the parameter
ENABLE_GZIP = trueThere is no additional parameter related to tar.*.command as stated in #26620 . Gitea has the default behavior here.
As sometimes there can be a problem due to the reverse proxy nginx in front wich also has gzip=on, I did some tests without it.
It was completely bypassed, connected directly to the gitea instance/port.
Results are :
It is worth noting the files generated by Gitea in its cache under
repo-archive/*hash*.tar.gzare valid.Included those who were already generated and still in Gitea local cache.
I also think ENABLE_GZIP does not do what is stated in the documentation : when set to false, without a reverse proxy most of the data was still sent gzipped. What is the real use for ?
Gitea Version
1.21.9 and 1.21.11
Can you reproduce the bug on the Gitea demo site?
No
Log Gist
No response
Screenshots
No response
Git Version
2.17.1
Operating System
Ubuntu 18.04
How are you running Gitea?
Binary release from https://github.com/go-gitea/gitea/releases
Launched by systemd
Database
SQLite
@wxiaoguang commented on GitHub (Apr 23, 2024):
If it is related to
ENABLE_GZIP=true, could you try the 1.21 nightly (https://dl.gitea.com/gitea/1.21/) ? It has a new gzip handler.It doesn't seem to be possible. At least, according to the code, the "gzip handler" is only used when
ENABLE_GZIP=true.Could you provide more details about which page is sent as gzip when ENABLE_GZIP=false?
fcdc57d811/routers/web/web.go (L246-L254)@Daryes commented on GitHub (Apr 24, 2024):
Hello,
Tested with this binary : gitea-1.21-linux-amd64
Same behavior, no change : With ENABLE_GZIP,=true the .tar.gz files are compressed a second time.
Well, then, the plot thickens ...
Reran some tests, no reverse proxy, http connection, cache disabled in the browser, and "ENABLE_GZIP=false" in app.ini.
The following files are always gziped : webcomponents.js, index.js, index.css, logo.svg (the gitea one).
On the other hand, index.html page and anything .json related are not compressed, as expected.
The http request/response for index.css with ENABLE_GZIP=false
With ENABLE_GZIP=true, everything is compressed, images aside.
The problem with the .tar.gz files is helpful to validate the setting value.
Also, this might be the source of the problem for the double compression of the .tar.gz files : some mimetype exclusions could be missing in the code.
This aside, static resources or heavy files with an enforced compression do not strike me as a wrong idea. Just, yeah, seems some part of the documentation and code need a pass or 2.
@wxiaoguang commented on GitHub (Apr 25, 2024):
Thank you for the details. I will try to answer the questions by my understanding.
For the ENABLE_GZIP option itself:
Gitea has 2 different web request handlers.
For the "tar.gz" problem itself, I did a quick test by these steps:
Use the docker compose:
Test the gzip is really enabled:
Create a repo named "test-archive", then download the tar.gz archive:
I think it works well.
@Daryes commented on GitHub (Apr 25, 2024):
I can confirm your test for a new repo, with a default readme.md : the tar.gz file is correct.
be it from wget or using a browser.
I can also confirm this behavior is not the norm. The trigger is having the repo to a minimum size.
There's also the fact I was running wget with some environment parameters activating gzip.
With your new repo test and ENABLE_GZIP=true :
Please note the response headers are also not the same between gzip encoding activated or not
And using a browser will also return a double gzipped archive, due to the fact it will by default accepted gzip encoded data.
So to summarize :
ENABLE_GZIP=true set in Gitea configuration
the target repo must have a minimal size to trigger Gitea gzip encoder on http connections. The default readme.md from a new repo is clearly not enough.
wget in its default configuration will not support gzip encoded data and will not trigger the double compressed archive.
any client (browser, curl, wget) with a configuration where gzip encoding is explicitly accepted will trigger the double compressed archive
@wxiaoguang commented on GitHub (Apr 25, 2024):
Oops, my bad .... I forgot the minimal gzip threshold 😢 you are right, I will take a look again later.
@wxiaoguang commented on GitHub (Apr 26, 2024):
Tested again with my docker compose in https://github.com/go-gitea/gitea/issues/30649#issuecomment-2076125979 .
This time, I uploaded a large avatar.png to the repo (170KB)
It seems that my
taris too smart, it is able to un-archive the double-gzipped file .......Outdated, see below.
@wxiaoguang commented on GitHub (Apr 26, 2024):
After more testing, I think the problem is clear now. I think the gzip compression is not wrong. There are some cases:
Content-Encoding: gzipheader, and decompress the received content automatically, and write the decompressed data into file.--header="accept-encoding: gzipmanually, wget won't decompress the transferred content automatically. It only writes what it received into file.About this:
That's expected and correct behavior. If you would like to make "curl" work with "gzip" transparently, it should use
curl --compressed. https://stackoverflow.com/questions/18983719/is-there-any-way-to-get-curl-to-decompress-a-response-without-sending-the-acceptSee the differences by:
@wxiaoguang commented on GitHub (Apr 30, 2024):
So I think this issue could be closed?
@Daryes commented on GitHub (Apr 30, 2024):
No.
Not for me anyway.
I've said it before, the browser is also not handling the tar.gz properly. As its true I didn't specify the version, here it is : Firefox ESR 115.10 (latest).
Btw, I tend to favor tar.gz files from repos as they will manage correctly symlinks and other *nix special files that zip sometimes cannot, and will not warn about.
This said, with ENABLE_GZIP on, currently, wget and firefox do not save a valid tar.gz file.
One client in error, could be it, 2 different clients ? Might be server side instead.
Never before I had to specify --compress explicitly in either curl or wget to download an archive from a webserver. If the content is wrong, it is then either badly handled by the webserver, or sent without the correct information.
What could be the source of the problem seems to circle around the response header
Content-Typesent by Gitea.It is
Content-Type: application/octet-streamfor zip AND tar.gz archives.Which is wrong for both if they must be managed by the client.
While it is usually used to force the client to save the data in a file as per the RFC 2046, given it is an arbitrary data, it leaves to the client how it will be handled.
Now, combine those 3 headers sent to the client
How it will be handled will depend of the client, as the type octet-stream has no real mandatory definition about how to managed it, aside being saved as a file (mind the fact this is also just a recommendation originally in said RFC).
Either the client is blind and applies the content-encoding, stating gzip => uncompress the content.
Or it tries to be smart due to so much bad implementation or configuration since decades, and with an arbitrary data type, will seek the filename information in the content-disposition header.
This scenario would explain the situation.
It could be validated with a proxy and force-rewriting the content-type header. Not hard, but already too much work for this.
I did much more digging on this than intended, for something that was in the end not correctly implemented since start, from my point of view.
I would like to remind that activating deflate or zip on a webserver is done using mimetype to ensure already compressed data (archive, images, crypted files, ...) is not compressed another time.
It is a waste of cpu cycles, and gzipping everything without regard to the data nor the size tends to give the opposite effect from what was desired.
The parameter ENABLE_GZIP should be either set to false as default (which is the current, so good already) but also masked/removed from the documentation, leaving the "full" compression to a reverse proxy like nginx or traefik.
Or keeping it but after a rewrite to manage exclusions, for properly compressing or leaving untouched the data depending of the real type.
@wxiaoguang commented on GitHub (May 1, 2024):
Thank you for more feedbacks. Let's do a quick test:
This test is still based on my provided docker compose, with a large file in it:
wget -O test-no-gzip.zip http://localhost:3002/root/test-gzip/archive/main.ziptest-no-gzip.zip: Zip archive data, at least v1.0 to extract, compression method=storewget -O test-with-gzip.zip --header="accept-encoding: gzip" http://localhost:3002/root/test-gzip/archive/main.ziptest-with-gzip.zip: gzip compressed data, original size modulo 2^32 170400accept-encoding: gzipis set, then the saved content should be gzipped again, because client shouldn't transparently decompress the transferred content.Downloads/test-gzip-main.zip: Zip archive data, at least v1.0 to extract, compression method=storegunzip test-gzip-main.tar.gz && file test-gzip-main.tartest-gzip-main.tar: POSIX tar archiveConclusion:
"accept-encoding: gzip"is not the correct method in daily usage, it prevent the client from transparently handling the transport encoding.About your question:
These headers are right (at least, not wrong).
Content-Encodingis for transporting, it should be handled transparently by the clients. After the transport is correctly handled and client gets "processed content (decompressed)", then the client could useContent-Dispositionto know to write the processed content into a file, and the content type isapplication/octet-stream(for downloading, the content type doesn't really matter)I also agree that when transferring some compressed contents, using gzip to compress the data on wire again is not ideal (and unnecessary), while indeed it won't (and shouldn't) cause any real problem at the moment. I think the behavior could be improved if the 3rd gzip handler could be more smarter when it detects if the content is compressed .......... and maybe it could also hard-code something on Gitea side.
@wxiaoguang commented on GitHub (May 1, 2024):
As a quick fix, it could be like this: Skip gzip for some well-known compressed file types #30796
@wxiaoguang commented on GitHub (May 2, 2024):
#30796 and its backport have been merged. Feel free to try 1.22-nightly
@wxiaoguang commented on GitHub (May 6, 2024):
Are there still any problems? Or maybe this issue could be closed?
@Daryes commented on GitHub (May 6, 2024):
I didn't test it yet, but I don't see why it wouldn't work given the changes you did.
Btw, I would like to thank you for your work, I didn't expect it would be resolved.
@Daryes commented on GitHub (May 12, 2024):
Just tested, working fine with already compressed files while retaining the gzip compression for the other files.
Thanks