我开始在Go中编写服务器端应用程序。我想使用Accept-Encoding请求标头来确定是否GZIP响应实体。我曾希望使用http.Serve或http.ServeFile方法直接找到一种方法。
这是一个非常普遍的要求;我错过了什么或者我需要推出自己的解决方案吗?
答案 0 :(得分:20)
gzip压缩的HTTP响应还没有“开箱即用”的支持。但添加它是非常微不足道的。看看
https://gist.github.com/the42/1956518
也
https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/cgUp8_ATNtc
答案 1 :(得分:20)
“纽约时报”发布了gzip middleware package for Go。
您只需将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)
}
答案 2 :(得分:1)
出于完整性考虑,我最终用一个简单的处理程序回答了自己的问题,该处理程序专门用于解决此问题。
这会从Go http服务器提供静态文件,包括要求的性能增强功能。它基于标准的net / http ServeFiles,具有gzip / brotli和缓存性能增强。
答案 3 :(得分: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)))
}