英文:
Serving gzipped content for Go
问题
我开始用Go编写服务器端应用程序。我想使用Accept-Encoding
请求头来确定是否使用GZIP
压缩响应实体。我本希望能够直接使用http.Serve
或http.ServeFile
方法来实现这一点。
这是一个相当普遍的需求;我有遗漏了什么,还是需要自己解决?
英文:
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 using GZIP
. I had hoped to find a way to do this directly using the http.Serve
or http.ServeFile
methods.
This is quite a general requirement; did I miss something or do I need to roll my own solution?
答案1
得分: 29
纽约时报已经发布了他们的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)
}
英文:
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)
}
答案2
得分: 28
目前还没有“开箱即用”的支持gzip压缩的HTTP响应。但是添加它非常简单。请查看以下链接:
https://gist.github.com/the42/1956518
还有
https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/cgUp8_ATNtc
英文:
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
答案3
得分: 2
为了完整起见,我最终用一个简单且专门解决这个问题的处理程序回答了自己的问题。
这个处理程序从Go http服务器中提供静态文件,包括所需的性能增强功能。它基于标准的net/http ServeFiles,具有gzip/brotli和缓存性能增强功能。
英文:
For the sake of completeness, I eventually answered my own question with a handler that is simple and specialises in solving this issue.
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.
答案4
得分: 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)))
})
// 使用默认设置包装http.Handler
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示例:
import github.com/nanmu42/gzip
func main() {
g := gin.Default()
// 使用默认设置
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)))
}
英文:
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)))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论