适用于 Gin 和 net/http 的 gzip 中间件,基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩

本贴最后更新于 1808 天前,其中的信息可能已经天翻地覆

gzip 中间件

项目地址:https://github.com/nanmu42/gzip

适用于 Ginnet/http 的 gzip 中间件。基于 Content-TypeContent-Length、扩展名等要素自动判断是否启用压缩。

使用示例

GoDoc

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

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

    // 使用默认设定
	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")
}

定制 Handler

在创建 Handler 时,可以定制参数以满足你的需要:

import github.com/nanmu42/gzip

handler := gzip.NewHandler(gzip.Config{
    // gzip压缩等级
	CompressionLevel: 6,
    // 使用gzip的最小body体积,单位:byte
	MinContentLength: 256,
    // 请求过滤器基于请求来判断是否对这条请求的返回启用gzip,
    // 过滤器按其定义顺序执行,下同。
	RequestFilter: []RequestFilter{
	    NewCommonRequestFilter(),
	    DefaultExtensionFilter(),
	},
    // 返回header过滤器基于返回的header判断是否对这条请求的返回启用gzip
	ResponseHeaderFilter: []ResponseHeaderFilter{
		NewSkipCompressedFilter(),
		DefaultContentTypeFilter(),
	},
})

RequestFilterResponseHeaderFilter 是 interface.
你可以实现你自己的过滤器。

Handler 的局限性

  • 总是在返回中提供 Content-Type,Handler 不会对未知 Content-Type 的返回进行类型猜测;
  • Handler 会先在返回的 Content-Length 中查询 body 体积,如果没有就再查看 http.ResponseWriter.Write(data []byte) 在首次调用时的 len(data) 作为参考。倘若返回的 Content-Length 不存在,且 http.ResponseWriter.Write(data []byte) 首次调用时的 len(data) 较小,这条返回会被错误认为无需压缩。

如果你使用的是 Gin 的 c.JSON()c.PureJSON(),无需担心上述问题。

如果你直接使用 net/http,请妥善处理上述问题。

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 285 关注
  • Gin
    12 引用 • 33 回帖
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 135 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    179 引用 • 995 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...