{"id":13789246,"url":"https://github.com/nanmu42/gzip","last_synced_at":"2025-10-25T08:05:17.713Z","repository":{"id":46998181,"uuid":"226004454","full_name":"nanmu42/gzip","owner":"nanmu42","description":":floppy_disk: Golang gzip middleware for Gin and net/http | Golang gzip中间件，支持Gin和net/http，开箱即用同时可定制","archived":false,"fork":false,"pushed_at":"2023-03-10T03:44:53.000Z","size":141,"stargazers_count":144,"open_issues_count":2,"forks_count":13,"subscribers_count":4,"default_branch":"v1","last_synced_at":"2025-03-30T06:41:18.707Z","etag":null,"topics":["compression","content-length","content-type","gin","gin-middleware","go","golang","gzip","http","middleware"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nanmu42.png","metadata":{"files":{"readme":"README.Chinese.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"nanmu42"}},"created_at":"2019-12-05T03:03:55.000Z","updated_at":"2025-01-07T03:16:54.000Z","dependencies_parsed_at":"2024-06-18T15:28:44.581Z","dependency_job_id":"17747ba9-477c-4bf6-8fd9-55c9b960612f","html_url":"https://github.com/nanmu42/gzip","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanmu42%2Fgzip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanmu42%2Fgzip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanmu42%2Fgzip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanmu42%2Fgzip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nanmu42","download_url":"https://codeload.github.com/nanmu42/gzip/tar.gz/refs/heads/v1","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250560034,"owners_count":21450170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compression","content-length","content-type","gin","gin-middleware","go","golang","gzip","http","middleware"],"created_at":"2024-08-03T21:01:00.551Z","updated_at":"2025-10-25T08:05:17.707Z","avatar_url":"https://github.com/nanmu42.png","language":"Go","funding_links":["https://github.com/sponsors/nanmu42"],"categories":["Go"],"sub_categories":[],"readme":"[English](https://github.com/nanmu42/gzip/blob/master/README.md) | **中文**\n\n# gzip\n\n[![GoDoc](https://godoc.org/github.com/nanmu42/gzip?status.svg)](https://godoc.org/github.com/nanmu42/gzip)\n[![Build status](https://github.com/nanmu42/gzip/workflows/build/badge.svg)](https://github.com/nanmu42/gzip/actions)\n[![codecov](https://codecov.io/gh/nanmu42/gzip/branch/master/graph/badge.svg)](https://codecov.io/gh/nanmu42/gzip)\n[![Lint status](https://github.com/nanmu42/gzip/workflows/golangci-lint/badge.svg)](https://github.com/nanmu42/gzip/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nanmu42/gzip)](https://goreportcard.com/report/github.com/nanmu42/gzip)\n\n一个开箱即用，可定制，适用于[Gin](https://github.com/gin-gonic/gin)和[net/http](https://golang.org/pkg/net/http/)的gzip中间件。\n\n![Golang Gzip Middleware](https://repository-images.githubusercontent.com/226004454/598f2e80-87a9-11ea-8c80-ecfc0e85fef5)\n\n# 使用示例\n\n默认设置`DefaultHandler()`可以满足大部分场景。\n\n## Gin\n\n```go\nimport github.com/nanmu42/gzip\n\nfunc main() {\n\tg := gin.Default()\n\t\n    // 使用默认设定\n\tg.Use(gzip.DefaultHandler().Gin)\n\n\tg.GET(\"/\", func(c *gin.Context) {\n\t\tc.JSON(http.StatusOK, map[string]interface{}{\n\t\t\t\"code\": 0,\n\t\t\t\"msg\":  \"hello\",\n\t\t\t\"data\": fmt.Sprintf(\"l%sng!\", strings.Repeat(\"o\", 1000)),\n\t\t})\n\t})\n\n\tlog.Println(g.Run(fmt.Sprintf(\":%d\", 3000)))\n}\n```\n\n## net/http\n\n```go\nimport github.com/nanmu42/gzip\n\nfunc main() {\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\twriteString(w, fmt.Sprintf(\"This content is compressed: l%sng!\", strings.Repeat(\"o\", 1000)))\n\t})\n\n    // 使用默认设定\n\tlog.Println(http.ListenAndServe(fmt.Sprintf(\":%d\", 3001), gzip.DefaultHandler().WrapHandler(mux)))\n}\n\nfunc writeString(w http.ResponseWriter, payload string) {\n\tw.Header().Set(\"Content-Type\", \"text/plain; charset=utf8\")\n\t_, _ = io.WriteString(w, payload+\"\\n\")\n}\n```\n\n## 定制`Handler`\n\n使用`NewHandler()`可以定制参数以满足你的特殊需要：\n\n```go\nimport github.com/nanmu42/gzip\n\nhandler := gzip.NewHandler(gzip.Config{\n    // gzip压缩等级\n\tCompressionLevel: 6,\n    // 触发gzip的最小body体积，单位：byte\n\tMinContentLength: 1024,\n    // 请求过滤器基于请求来判断是否对这条请求的返回启用gzip，\n    // 过滤器按其定义顺序执行，下同。\n\tRequestFilter: []RequestFilter{\n\t    NewCommonRequestFilter(),\n\t    DefaultExtensionFilter(),\n\t},\n    // 返回header过滤器基于返回的header判断是否对这条请求的返回启用gzip\n\tResponseHeaderFilter: []ResponseHeaderFilter{\n\t\tNewSkipCompressedFilter(),\n\t\tDefaultContentTypeFilter(),\n\t},\n})\n```\n\n`RequestFilter` 和 `ResponseHeaderFilter` 是 interface.\n你可以实现你自己的过滤器。\n\n# 效率\n\n* 当返回体积不大时，Handler会智能地跳过压缩，这个过程带来的代价可以忽略不记；\n* 当返回体积足够大时，Handler会进行gzip压缩，这个过程有着合理的代价。\n\n```\n$ go test -benchmem -bench .\ngoos: linux\ngoarch: amd64\npkg: github.com/nanmu42/gzip\nBenchmarkSoleGin_SmallPayload-4                          4104684               276 ns/op              64 B/op          2 allocs/op\nBenchmarkGinWithDefaultHandler_SmallPayload-4            1683307               707 ns/op              96 B/op          3 allocs/op\nBenchmarkSoleGin_BigPayload-4                            4198786               274 ns/op              64 B/op          2 allocs/op\nBenchmarkGinWithDefaultHandler_BigPayload-4                44780             27636 ns/op             190 B/op          5 allocs/op\nPASS\nok      github.com/nanmu42/gzip 6.373s\n```\n\n注：由于[一个笨拙的人为错误](https://github.com/nanmu42/gzip/pull/3#issuecomment-735352715)，`v1.0.0`以及更早版本的评测指标是错误的，不具有参考意义。\n\n# 局限性\n\n* 你应该总是在返回中提供`Content-Type`。虽然Handler会在`Content-Type`缺失时使用`http.DetectContentType()`进行猜测，但是效果并没有那么好；\n* 返回的`Content-Length` 缺失时，Handler可能会缓冲返回的报文数据以决定报文是否大到值得进行压缩，如果`MinContentLength`设置得太大，这个过程可能会带来内存压力。Handler针对这个情况做了一些优化，例如查看`http.ResponseWriter.Write(data []byte)`在首次调用时的 `len(data)`，以及资源复用。\n\n# 项目状态：稳定\n\nAPI已经稳定，`1.x`版本中的更新会向前兼容。\n\n# 致谢\n\n在本项目的开发中，作者参考了下列项目和资料：\n\n* https://github.com/caddyserver/caddy/tree/master/caddyhttp/gzip (Apache License 2.0)\n* https://github.com/gin-contrib/gzip (MIT License)\n* https://blog.cloudflare.com/results-experimenting-brotli/\n* https://support.cloudflare.com/hc/en-us/articles/200168396-What-will-Cloudflare-compress-\n\n本项目使用[klauspost的compress库](https://github.com/klauspost/compress)中的gzip压缩实现。\n\nLogo在[Gopherize.me](https://gopherize.me/)生成。\n\n# License\n\n```\nMIT License\nCopyright (c) 2019 LI Zhennan\n\nCaddy is licensed under the Apache License\nCopyright 2015 Light Code Labs, LLC\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanmu42%2Fgzip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnanmu42%2Fgzip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanmu42%2Fgzip/lists"}