为Go提供gzip压缩内容

huangapple go评论149阅读模式
英文:

Serving gzipped content for Go

问题

我开始用Go编写服务器端应用程序。我想使用Accept-Encoding请求头来确定是否使用GZIP压缩响应实体。我本希望能够直接使用http.Servehttp.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)))
}

huangapple
  • 本文由 发表于 2012年12月29日 01:34:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/14073393.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定