Skip to content

Instantly share code, notes, and snippets.

Last active Nov 22, 2022
What would you like to do?
Idiomatic golang net/http gzip transparent compression (works with Alice)
package main
import (
// Gzip Compression
type gzipResponseWriter struct {
func (w gzipResponseWriter) Write(b []byte) (int, error) {
return w.Writer.Write(b)
func Gzip(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
handler.ServeHTTP(w, r)
w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
handler.ServeHTTP(gzw, r)
Copy link

roustem commented Sep 25, 2015

Missing return after line 23?

Copy link

yes, that return seems to be missing ;)

Copy link

Content negotiation is overrated. Make way for CONTENT DICTATORSHIP!

Copy link

mappu commented Jul 31, 2017

This gist is currently the second google result for "golang gzip http" and the first google result for some related terms.

About content-length

If your upstream writer sets Content-Length, this will result in the wrong (smaller) length being passed to the client. The middleware should remove any Content-Length header set by the upstream writer.

  • This cannot be done in the Gzip() function since the handler hasn't been called yet.
  • You could either overwrite WriteHeader, or, check if headers have been sent in the first call to Write and remove the Content-Length header then.
  • Tracking state of this process necessitates converting from value receiver to pointer receiver.

About sync.Pool

Performance of regularly creating gzip writers is non-optimal. The gzip writer should be kept in a sync.Pool for reuse to minimise GC pressure.

Copy link

ahmetb commented Mar 27, 2018

I reached out to the owner of the gist to fix the update.

Copy link

Is there any further example of this gzip compression that also using the sync.Pool as per @mappu said ?

Copy link

Here's an updated version if anyone's interested:

Copy link

lyda commented Jun 23, 2019

In the case of serving a file, would it be an option to look for an already compressed version of the file?

Copy link

jftuga commented Apr 16, 2020

For max compression:

gzip.NewWriterLevel(w, gzip.BestCompression)

Copy link

cli-ish commented Apr 29, 2022

Content negotiation is overrated. Make way for CONTENT DICTATORSHIP!

Pure gold, was just seeking for a solution and found this 😄

Copy link

TelephoneTan commented Sep 1, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment