pquerna/cachecontrol
GitHub: pquerna/cachecontrol
一个 Go 语言实现的 HTTP Cache-Control 头解析与缓存可判定库,依据 RFC 7234 规范计算响应的可缓存性与过期时间。
Stars: 150 | Forks: 18
# cachecontrol:HTTP 缓存解析器与解释
[](https://pkg.go.dev/github.com/pquerna/cachecontrol?tab=doc)[](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开发, 安全编程, 日志审计, 缓存控制, 解析器