43

我开始用 Go 编写服务器端应用程序。我想使用Accept-Encoding请求标头来确定是否使用GZIP. 我曾希望找到一种直接使用http.Serveor方法的http.ServeFile方法。

这是一个相当普遍的要求;我错过了什么还是我需要推出自己的解决方案?

4

4 回答 4

28

纽约时报已经发布了他们的 Go 的 gzip 中间件包

你只需http.HandlerFunc通过他们GzipHandler,你就完成了。它看起来像这样:

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)
}
于 2015-12-19T16:45:55.973 回答
25

目前还没有对 gzip 压缩的 HTTP 响应的“开箱即用”支持。但是添加它是非常微不足道的。看一下

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

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

于 2012-12-28T23:17:43.033 回答
2

为了完整起见,我最终用一个简单且专门解决此问题的处理程序回答了我自己的问题。

这提供来自 Go http 服务器的静态文件,包括要求的性能增强功能。它基于标准的 net/http ServeFiles,具有 gzip/brotli 和缓存性能增强。

于 2020-07-16T12:48:21.023 回答
0

现在还有另一个“开箱即用”的中间件,支持net/http和 Gin:

https://github.com/nanmu42/gzip

net/http例子:

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")
}

杜松子酒示例:

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)))
}
于 2020-04-11T08:40:35.413 回答