pquerna/cachecontrol

GitHub: pquerna/cachecontrol

一个 Go 语言实现的 HTTP Cache-Control 头解析与缓存可判定库,依据 RFC 7234 规范计算响应的可缓存性与过期时间。

Stars: 150 | Forks: 18

# cachecontrol:HTTP 缓存解析器与解释 [![PkgGoDev](https://pkg.go.dev/badge/github.com/pquerna/cachecontrol?tab=doc)](https://pkg.go.dev/github.com/pquerna/cachecontrol?tab=doc)[![构建状态](https://travis-ci.org/pquerna/cachecontrol.svg?branch=main)](https://travis-ci.org/pquerna/cachecontrol) `cachecontrol` 实现了 [RFC 7234](http://tools.ietf.org/html/rfc7234) __超文本传输协议 (HTTP/1.1):缓存__。它通过解析 `Cache-Control` 及其他 HTTP 头来实现这一点,提供有关请求和响应的信息——但 `cachecontrol` 并不实现实际的缓存后端,它仅仅提供控制层面,用于决定某个特定响应是否可缓存。 # 用法 `cachecontrol.CachableResponse` 返回一组[原因](https://godoc.org/github.com/pquerna/cachecontrol/cacheobject#Reason),说明为什么响应不应被缓存以及它何时过期。在 `len(reasons) == 0` 的情况下,根据 RFC 规范,该响应是可缓存的。然而,出于各种业务用例的需求,有些人可能希望使用不完全符合规范的缓存,因此每个原因都有具体的命名。这样一来,如果你的缓存希望缓存 `POST` 请求,它可以轻松做到这一点,同时在其他情况下仍然保持对 RFC 规范的遵循。 # 示例 ## 你能缓存 Example.com 吗? ``` package main import ( "github.com/pquerna/cachecontrol" "fmt" "io/ioutil" "net/http" ) func main() { req, _ := http.NewRequest("GET", "http://www.example.com/", nil) res, _ := http.DefaultClient.Do(req) _, _ = ioutil.ReadAll(res.Body) reasons, expires, _ := cachecontrol.CachableResponse(req, res, cachecontrol.Options{}) fmt.Println("Reasons to not cache: ", reasons) fmt.Println("Expiration: ", expires.String()) } ``` ## 我可以在高性能缓存服务器中使用它吗? `cachecontrol` 分为两个包:提供高级 API 的 `cachecontrol`,以及较低级别的 `cacheobject` 包。如果你已经预先解析了包含日期的 HTTP 头,或者希望避免内存分配,可以在高性能用例中使用 [Object](https://godoc.org/github.com/pquerna/cachecontrol/cacheobject#Object)。 ``` package main import ( "github.com/pquerna/cachecontrol/cacheobject" "fmt" "io/ioutil" "net/http" ) func main() { req, _ := http.NewRequest("GET", "http://www.example.com/", nil) res, _ := http.DefaultClient.Do(req) _, _ = ioutil.ReadAll(res.Body) reqDir, _ := cacheobject.ParseRequestCacheControl(req.Header.Get("Cache-Control")) resDir, _ := cacheobject.ParseResponseCacheControl(res.Header.Get("Cache-Control")) expiresHeader, _ := http.ParseTime(res.Header.Get("Expires")) dateHeader, _ := http.ParseTime(res.Header.Get("Date")) lastModifiedHeader, _ := http.ParseTime(res.Header.Get("Last-Modified")) obj := cacheobject.Object{ RespDirectives: resDir, RespHeaders: res.Header, RespStatusCode: res.StatusCode, RespExpiresHeader: expiresHeader, RespDateHeader: dateHeader, RespLastModifiedHeader: lastModifiedHeader, ReqDirectives: reqDir, ReqHeaders: req.Header, ReqMethod: req.Method, NowUTC: time.Now().UTC(), } rv := cacheobject.ObjectResults{} cacheobject.CachableObject(&obj, &rv) cacheobject.ExpirationObject(&obj, &rv) fmt.Println("Errors: ", rv.OutErr) fmt.Println("Reasons to not cache: ", rv.OutReasons) fmt.Println("Warning headers to add: ", rv.OutWarnings) fmt.Println("Expiration: ", rv.OutExpirationTime.String()) } ``` ## 改进、Bug、添加功能以及为 cachecontrol 探索新方向! 请[在 Github 中开启 issue](https://github.com/pquerna/cachecontrol/issues) 分享你的想法、Bug 和总体建议。当然,更欢迎提交 Pull request :) # 致谢 `cachecontrol` 得到了以下人员的重要贡献: * [Paul Querna](https://github.com/pquerna) ## 许可证 `cachecontrol` 采用 [Apache License, Version 2.0](./LICENSE) 授权
标签:EVTX分析, Golang, RFC 7234, Syscall, Web开发, 安全编程, 日志审计, 缓存控制, 解析器