Serving gzipped content for Go

后端 未结 4 2004
死守一世寂寞
死守一世寂寞 2021-01-30 17:00

I\'m starting to write server-side applications in Go. I\'d like to use the Accept-Encoding request header to determine whether to compress the response entity usi

相关标签:
4条回答
  • 2021-01-30 17:13

    The New York Times have released their gzip middleware package for Go.

    You just pass your http.HandlerFunc through their GzipHandler and you're done. It looks like this:

    package main
    
    import (
        "io"
        "net/http"
        "github.com/nytimes/gziphandler"
    )
    
    func main() {
        withoutGz := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Content-Type", "text/plain")
            io.WriteString(w, "Hello, World")
        })
    
        withGz := gziphandler.GzipHandler(withoutGz)
    
        http.Handle("/", withGz)
        http.ListenAndServe("0.0.0.0:8000", nil)
    }
    
    0 讨论(0)
  • 2021-01-30 17:20

    There is no “out of the box” support for gzip-compressed HTTP responses yet. But adding it is pretty trivial. Have a look at

    https://gist.github.com/the42/1956518

    also

    https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/cgUp8_ATNtc

    0 讨论(0)
  • 2021-01-30 17:24

    There is yet another "out of the box" middleware now, supporting net/http and Gin:

    https://github.com/nanmu42/gzip

    net/http example:

    import github.com/nanmu42/gzip
    
    func main() {
        mux := http.NewServeMux()
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            writeString(w, fmt.Sprintf("This content is compressed: l%sng!", strings.Repeat("o", 1000)))
        })
    
        // wrap http.Handler using default settings
        log.Println(http.ListenAndServe(fmt.Sprintf(":%d", 3001), gzip.DefaultHandler().WrapHandler(mux)))
    }
    
    func writeString(w http.ResponseWriter, payload string) {
        w.Header().Set("Content-Type", "text/plain; charset=utf8")
        _, _ = io.WriteString(w, payload+"\n")
    }
    

    Gin example:

    import github.com/nanmu42/gzip
    
    func main() {
        g := gin.Default()
    
        // use default settings
        g.Use(gzip.DefaultHandler().Gin)
    
        g.GET("/", func(c *gin.Context) {
            c.JSON(http.StatusOK, map[string]interface{}{
                "code": 0,
                "msg":  "hello",
                "data": fmt.Sprintf("l%sng!", strings.Repeat("o", 1000)),
            })
        })
    
        log.Println(g.Run(fmt.Sprintf(":%d", 3000)))
    }
    
    0 讨论(0)
  • 2021-01-30 17:31

    For the sake of completeness, I eventually answered my own question with a handler that is simple and specialises in solving this issue.

    • https://pkg.go.dev/github.com/rickb777/servefiles?tab=doc
    • https://github.com/rickb777/servefiles

    This serves static files from a Go http server, including the asked-for performance-enhancing features. It is based on the standard net/http ServeFiles, with gzip/brotli and cache performance enhancements.

    0 讨论(0)
提交回复
热议问题