0

How can I enable gzip compression using the gzip middleware of the go-chi framework?

Try using the example shown here:

https://github.com/go-chi/chi/issues/204

but when I check with curl, I get this:

$ curl -H "Accept-Encoding: gzip" -I http://127.0.0.1:3333
HTTP/1.1 405 Method Not Allowed
Date: Sat, 31 Aug 2019 19:06:39 GMT

I tried the code "hello world":

package main

import (
    "net/http"

    "github.com/go-chi/chi"
    "github.com/go-chi/chi/middleware"
)

func main() {
    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(middleware.Logger)
    //r.Use(middleware.DefaultCompress) //using this produces the same result
    r.Use(middleware.Compress(5, "gzip"))
    r.Get("/", Hello)
    http.ListenAndServe(":3333", r)
}

func Hello(w http.ResponseWriter, r *http.Request){
    w.Header().Set("Content-Type", "text/html") //according to the documentation this must be here to enable gzip
    w.Write([]byte("hello world\n"))
}

but when I try to verify with curl, the result is the same

$ curl -H "Accept-Encoding: gzip" -I http://127.0.0.1:3333
HTTP/1.1 405 Method Not Allowed
Date: Sat, 31 Aug 2019 19:06:39 GMT

what's going on?

jhoss
  • 457
  • 3
  • 10
  • 19

3 Answers3

13

The other answers are outdated now. I had to solve this myself, so here what I found out.

Your error is here:

r.Use(middleware.Compress(5, "gzip"))

The second argument ("types") refers to the content types that the compression will be applied to. For example: "text/html", "application/json", etc

Just add a list of the content-types you want to compress, or remove the argument altogether:

func main() {
    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(middleware.Logger)
    r.Use(middleware.Compress(5))
    r.Get("/", Hello)
    http.ListenAndServe(":3333", r)
}

This will compress all the content-types defined in the default list from middleware.Compress:

var defaultCompressibleContentTypes = []string{
    "text/html",
    "text/css",
    "text/plain",
    "text/javascript",
    "application/javascript",
    "application/x-javascript",
    "application/json",
    "application/atom+xml",
    "application/rss+xml",
    "image/svg+xml",
}

Good luck!

Mikel Pascual
  • 2,202
  • 18
  • 27
8

r.Use(middleware.DefaultCompress) has now been marked as DEPRECATED.

To enable compression you need to create a compressor, and use its handler.

r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.Logger)

compressor := middleware.NewCompressor(flate.DefaultCompression)
r.Use(compressor.Handler())

r.Get("/", Hello)
http.ListenAndServe(":3333", r)

The flate package must be imported as compress/flate.

Marco Borromeo
  • 308
  • 1
  • 3
  • 7
  • Thanks. To me, no "()" for "Handler": ``` compressor := middleware.NewCompressor(flate.DefaultCompression) r.Use(compressor.Handler) ``` – Leon Feb 05 '21 at 21:40
0

Use the commented middleware.DefaultCompress and a normal GET request.

package main

import (
    "net/http"

    "github.com/go-chi/chi"
    "github.com/go-chi/chi/middleware"
)

func main() {
    r := chi.NewRouter()
    r.Use(middleware.RequestID)
    r.Use(middleware.Logger)
    r.Use(middleware.DefaultCompress)
    r.Get("/", Hello)
    http.ListenAndServe(":3333", r)
}

func Hello(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/html")
    w.Write([]byte("hello world\n"))
}

Try with curl:

$ curl -v http://localhost:3333 --compressed
* Rebuilt URL to: http://localhost:3333/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3333 (#0)
> GET / HTTP/1.1
> Host: localhost:3333
> User-Agent: curl/7.58.0
> Accept: */*
> Accept-Encoding: deflate, gzip
>
< HTTP/1.1 200 OK
< Content-Encoding: gzip
< Content-Type: text/html
< Date: Sat, 31 Aug 2019 23:37:52 GMT
< Content-Length: 36
<
hello world
* Connection #0 to host localhost left intact

Or HTTPie:

$ http :3333
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 36
Content-Type: text/html
Date: Sat, 31 Aug 2019 23:38:31 GMT

hello world
Pablo Lalloni
  • 2,615
  • 19
  • 20