mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 15:51:54 +08:00 
			
		
		
		
	缓存支持ETag和Last-Modified
This commit is contained in:
		@@ -12,6 +12,9 @@ type Reader interface {
 | 
				
			|||||||
	// Status 状态码
 | 
						// Status 状态码
 | 
				
			||||||
	Status() int
 | 
						Status() int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// LastModified 最后修改时间
 | 
				
			||||||
 | 
						LastModified() int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ReadHeader 读取Header
 | 
						// ReadHeader 读取Header
 | 
				
			||||||
	ReadHeader(buf []byte, callback ReaderFunc) error
 | 
						ReadHeader(buf []byte, callback ReaderFunc) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -114,6 +114,14 @@ func (this *FileReader) Status() int {
 | 
				
			|||||||
	return this.status
 | 
						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 {
 | 
					func (this *FileReader) HeaderSize() int64 {
 | 
				
			||||||
	return int64(this.headerSize)
 | 
						return int64(this.headerSize)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,10 @@ func (this *MemoryReader) Status() int {
 | 
				
			|||||||
	return this.item.Status
 | 
						return this.item.Status
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *MemoryReader) LastModified() int64 {
 | 
				
			||||||
 | 
						return this.item.ModifiedAt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *MemoryReader) HeaderSize() int64 {
 | 
					func (this *MemoryReader) HeaderSize() int64 {
 | 
				
			||||||
	return int64(len(this.item.HeaderValue))
 | 
						return int64(len(this.item.HeaderValue))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ type MemoryItem struct {
 | 
				
			|||||||
	BodyValue   []byte
 | 
						BodyValue   []byte
 | 
				
			||||||
	Status      int
 | 
						Status      int
 | 
				
			||||||
	IsDone      bool
 | 
						IsDone      bool
 | 
				
			||||||
 | 
						ModifiedAt  int64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *MemoryItem) IsExpired() bool {
 | 
					func (this *MemoryItem) IsExpired() bool {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package caches
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/cespare/xxhash"
 | 
						"github.com/cespare/xxhash"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MemoryWriter struct {
 | 
					type MemoryWriter struct {
 | 
				
			||||||
@@ -26,8 +27,9 @@ func NewMemoryWriter(m map[uint64]*MemoryItem, key string, expiredAt int64, stat
 | 
				
			|||||||
		expiredAt: expiredAt,
 | 
							expiredAt: expiredAt,
 | 
				
			||||||
		locker:    locker,
 | 
							locker:    locker,
 | 
				
			||||||
		item: &MemoryItem{
 | 
							item: &MemoryItem{
 | 
				
			||||||
			ExpiredAt: expiredAt,
 | 
								ExpiredAt:  expiredAt,
 | 
				
			||||||
			Status:    status,
 | 
								ModifiedAt: time.Now().Unix(),
 | 
				
			||||||
 | 
								Status:     status,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		status:  status,
 | 
							status:  status,
 | 
				
			||||||
		endFunc: endFunc,
 | 
							endFunc: endFunc,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"github.com/iwind/TeaGo/logs"
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 读取缓存
 | 
					// 读取缓存
 | 
				
			||||||
@@ -120,6 +121,7 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		_ = reader.Close()
 | 
							_ = reader.Close()
 | 
				
			||||||
 | 
							this.cacheRef = nil // 终止读取不再往下传递
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.varMapping["cache.status"] = "HIT"
 | 
						this.varMapping["cache.status"] = "HIT"
 | 
				
			||||||
@@ -156,6 +158,45 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
 | 
				
			|||||||
	if addStatusHeader {
 | 
						if addStatusHeader {
 | 
				
			||||||
		this.writer.Header().Set("X-Cache", "HIT, "+refType+", "+reader.TypeName())
 | 
							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())
 | 
						this.processResponseHeaders(reader.Status())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 输出Body
 | 
						// 输出Body
 | 
				
			||||||
@@ -313,7 +354,6 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.cacheRef = nil // 终止读取不再往下传递
 | 
					 | 
				
			||||||
	this.isCached = true
 | 
						this.isCached = true
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,7 +162,7 @@ func (this *HTTPRequest) doReverseProxy() {
 | 
				
			|||||||
			// TODO 如果超过最大失败次数,则下线
 | 
								// TODO 如果超过最大失败次数,则下线
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.write502(err)
 | 
								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 {
 | 
							} else {
 | 
				
			||||||
			// 是否为客户端方面的错误
 | 
								// 是否为客户端方面的错误
 | 
				
			||||||
			isClientError := false
 | 
								isClientError := false
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user