mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	缓存支持ETag和Last-Modified
This commit is contained in:
		@@ -12,6 +12,9 @@ type Reader interface {
 | 
			
		||||
	// Status 状态码
 | 
			
		||||
	Status() int
 | 
			
		||||
 | 
			
		||||
	// LastModified 最后修改时间
 | 
			
		||||
	LastModified() int64
 | 
			
		||||
 | 
			
		||||
	// ReadHeader 读取Header
 | 
			
		||||
	ReadHeader(buf []byte, callback ReaderFunc) error
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ type MemoryItem struct {
 | 
			
		||||
	BodyValue   []byte
 | 
			
		||||
	Status      int
 | 
			
		||||
	IsDone      bool
 | 
			
		||||
	ModifiedAt  int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *MemoryItem) IsExpired() bool {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package caches
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/cespare/xxhash"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MemoryWriter struct {
 | 
			
		||||
@@ -26,8 +27,9 @@ func NewMemoryWriter(m map[uint64]*MemoryItem, key string, expiredAt int64, stat
 | 
			
		||||
		expiredAt: expiredAt,
 | 
			
		||||
		locker:    locker,
 | 
			
		||||
		item: &MemoryItem{
 | 
			
		||||
			ExpiredAt: expiredAt,
 | 
			
		||||
			Status:    status,
 | 
			
		||||
			ExpiredAt:  expiredAt,
 | 
			
		||||
			ModifiedAt: time.Now().Unix(),
 | 
			
		||||
			Status:     status,
 | 
			
		||||
		},
 | 
			
		||||
		status:  status,
 | 
			
		||||
		endFunc: endFunc,
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user