缓存支持ETag和Last-Modified

This commit is contained in:
GoEdgeLab
2021-06-14 11:46:39 +08:00
parent 0fff9186e5
commit 171d6632b7
7 changed files with 62 additions and 4 deletions

View File

@@ -12,6 +12,9 @@ type Reader interface {
// Status 状态码
Status() int
// LastModified 最后修改时间
LastModified() int64
// ReadHeader 读取Header
ReadHeader(buf []byte, callback ReaderFunc) error

View File

@@ -114,6 +114,14 @@ func (this *FileReader) Status() int {
return this.status
}
func (this *FileReader) LastModified() int64 {
stat, err := this.fp.Stat()
if err != nil {
return 0
}
return stat.ModTime().Unix()
}
func (this *FileReader) HeaderSize() int64 {
return int64(this.headerSize)
}

View File

@@ -24,6 +24,10 @@ func (this *MemoryReader) Status() int {
return this.item.Status
}
func (this *MemoryReader) LastModified() int64 {
return this.item.ModifiedAt
}
func (this *MemoryReader) HeaderSize() int64 {
return int64(len(this.item.HeaderValue))
}

View File

@@ -19,6 +19,7 @@ type MemoryItem struct {
BodyValue []byte
Status int
IsDone bool
ModifiedAt int64
}
func (this *MemoryItem) IsExpired() bool {

View File

@@ -3,6 +3,7 @@ package caches
import (
"github.com/cespare/xxhash"
"sync"
"time"
)
type MemoryWriter struct {
@@ -27,6 +28,7 @@ func NewMemoryWriter(m map[uint64]*MemoryItem, key string, expiredAt int64, stat
locker: locker,
item: &MemoryItem{
ExpiredAt: expiredAt,
ModifiedAt: time.Now().Unix(),
Status: status,
},
status: status,

View File

@@ -8,6 +8,7 @@ import (
"github.com/iwind/TeaGo/logs"
"net/http"
"strconv"
"time"
)
// 读取缓存
@@ -120,6 +121,7 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
}
defer func() {
_ = reader.Close()
this.cacheRef = nil // 终止读取不再往下传递
}()
this.varMapping["cache.status"] = "HIT"
@@ -156,6 +158,45 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
if addStatusHeader {
this.writer.Header().Set("X-Cache", "HIT, "+refType+", "+reader.TypeName())
}
// ETag
var respHeader = this.writer.Header()
var eTag = respHeader.Get("ETag")
var lastModifiedAt = reader.LastModified()
if len(eTag) == 0 {
if lastModifiedAt > 0 {
eTag = "\"" + strconv.FormatInt(lastModifiedAt, 10) + "\""
respHeader["ETag"] = []string{eTag}
}
}
// 支持 Last-Modified
var modifiedTime = respHeader.Get("Last-Modified")
if len(modifiedTime) == 0 {
if lastModifiedAt > 0 {
modifiedTime = time.Unix(lastModifiedAt, 0).Format("Mon, 02 Jan 2006 15:04:05 GMT")
if len(respHeader.Get("Last-Modified")) == 0 {
respHeader.Set("Last-Modified", modifiedTime)
}
}
}
// 支持 If-None-Match
if len(eTag) > 0 && this.requestHeader("If-None-Match") == eTag {
// 自定义Header
this.processResponseHeaders(http.StatusNotModified)
this.writer.WriteHeader(http.StatusNotModified)
return true
}
// 支持 If-Modified-Since
if len(modifiedTime) > 0 && this.requestHeader("If-Modified-Since") == modifiedTime {
// 自定义Header
this.processResponseHeaders(http.StatusNotModified)
this.writer.WriteHeader(http.StatusNotModified)
return true
}
this.processResponseHeaders(reader.Status())
// 输出Body
@@ -313,7 +354,6 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
}
}
this.cacheRef = nil // 终止读取不再往下传递
this.isCached = true
return true
}

View File

@@ -162,7 +162,7 @@ func (this *HTTPRequest) doReverseProxy() {
// TODO 如果超过最大失败次数,则下线
this.write502(err)
remotelogs.Println("HTTP_REQUEST_REVERSE_PROXY", this.RawReq.URL.String()+"': "+err.Error())
remotelogs.Warn("HTTP_REQUEST_REVERSE_PROXY", this.RawReq.URL.String()+"': "+err.Error())
} else {
// 是否为客户端方面的错误
isClientError := false