diff --git a/internal/nodes/api_stream.go b/internal/nodes/api_stream.go index 60719b8..796378e 100644 --- a/internal/nodes/api_stream.go +++ b/internal/nodes/api_stream.go @@ -356,6 +356,7 @@ func (this *APIStream) handlePurgeCache(message *pb.NodeStreamMessage) error { for _, encoding := range compressions.AllEncodings() { keys = append(keys, key+compressionCacheSuffix+encoding) keys = append(keys, key+webpCacheSuffix+compressionCacheSuffix+encoding) + keys = append(keys, key+cacheMethodSuffix+"HEAD") } } msg.Keys = keys diff --git a/internal/nodes/http_request_cache.go b/internal/nodes/http_request_cache.go index a9f2359..120fd6b 100644 --- a/internal/nodes/http_request_cache.go +++ b/internal/nodes/http_request_cache.go @@ -107,12 +107,20 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { // TODO 支持Vary Header + // 缓存标签 + var tags = []string{} + // 检查是否有缓存 - key := this.Format(this.cacheRef.Key) + var key = this.Format(this.cacheRef.Key) if len(key) == 0 { this.cacheRef = nil return } + var method = this.Method() + if method != http.MethodGet && method != http.MethodPost { + key += cacheMethodSuffix + method + tags = append(tags, strings.ToLower(method)) + } this.cacheKey = key this.varMapping["cache.key"] = key @@ -134,6 +142,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { for _, encoding := range compressions.AllEncodings() { subKeys = append(subKeys, key+compressionCacheSuffix+encoding) subKeys = append(subKeys, key+webpCacheSuffix+compressionCacheSuffix+encoding) + subKeys = append(subKeys, key+cacheMethodSuffix+"HEAD") } for _, subKey := range subKeys { err := storage.Delete(subKey) @@ -173,9 +182,10 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { var err error // 检查是否支持WebP - var tags = []string{} var webPIsEnabled = false - if this.web.WebP != nil && + var isHeadMethod = method == http.MethodHead + if !isHeadMethod && + this.web.WebP != nil && this.web.WebP.IsOn && this.web.WebP.MatchRequest(filepath.Ext(this.Path()), this.Format) && this.web.WebP.MatchAccept(this.RawReq.Header.Get("Accept")) { @@ -183,7 +193,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { } // 检查压缩缓存 - if reader == nil { + if !isHeadMethod && reader == nil { if this.web.Compression != nil && this.web.Compression.IsOn { _, encoding, ok := this.web.Compression.MatchAcceptEncoding(this.RawReq.Header.Get("Accept-Encoding")) if ok { @@ -207,7 +217,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { } // 检查WebP - if reader == nil && webPIsEnabled { + if !isHeadMethod && reader == nil && webPIsEnabled { reader, _ = storage.OpenReader(key+webpCacheSuffix, useStale) if reader != nil { this.writer.cacheReaderSuffix = webpCacheSuffix diff --git a/internal/nodes/http_writer.go b/internal/nodes/http_writer.go index ba3a126..0be0799 100644 --- a/internal/nodes/http_writer.go +++ b/internal/nodes/http_writer.go @@ -43,6 +43,9 @@ var webpTotalBufferSize int64 = 0 // 压缩相关配置 const compressionCacheSuffix = "@GOEDGE_" +// 缓存相关配置 +const cacheMethodSuffix = "@GOEDGE_" + func init() { var systemMemory = utils.SystemMemoryGB() / 8 if systemMemory > 0 { @@ -154,7 +157,7 @@ func (this *HTTPWriter) PrepareCache(resp *http.Response, size int64) { var addStatusHeader = this.req.web != nil && this.req.web.Cache != nil && this.req.web.Cache.AddStatusHeader // 不支持Range - if len(this.Header().Get("Content-Range")) > 0 { + if this.StatusCode() == http.StatusPartialContent || len(this.Header().Get("Content-Range")) > 0 { this.req.varMapping["cache.status"] = "BYPASS" if addStatusHeader { this.Header().Set("X-Cache", "BYPASS, not supported Content-Range") @@ -262,6 +265,10 @@ func (this *HTTPWriter) PrepareCache(resp *http.Response, size int64) { var expiredAt = utils.UnixTime() + life var cacheKey = this.req.cacheKey + var method = this.req.Method() + if method != http.MethodGet && method != http.MethodPost { + cacheKey += cacheMethodSuffix + this.req.Method() + } cacheWriter, err := storage.OpenWriter(cacheKey, expiredAt, this.StatusCode(), size, false) if err != nil { if !caches.CanIgnoreErr(err) { @@ -348,6 +355,15 @@ func (this *HTTPWriter) PrepareWebP(resp *http.Response, size int64) { // PrepareCompression 准备压缩 func (this *HTTPWriter) PrepareCompression(resp *http.Response, size int64) { + var method = this.req.Method() + if method == http.MethodHead { + return + } + + if this.StatusCode() == http.StatusNoContent { + return + } + var acceptEncodings = this.req.RawReq.Header.Get("Accept-Encoding") var contentEncoding = this.Header().Get("Content-Encoding") @@ -763,13 +779,16 @@ func (this *HTTPWriter) Close() { // 缓存 if this.cacheWriter != nil { if this.isOk && this.cacheIsFinished { - // 对比Content-Length - var contentLengthString = this.Header().Get("Content-Length") - if len(contentLengthString) > 0 { - var contentLength = types.Int64(contentLengthString) - if contentLength != this.cacheWriter.BodySize() { - this.isOk = false - _ = this.cacheWriter.Discard() + // 对比缓存前后的Content-Length + var method = this.req.Method() + if method != http.MethodHead && this.StatusCode() != http.StatusNoContent { + var contentLengthString = this.Header().Get("Content-Length") + if len(contentLengthString) > 0 { + var contentLength = types.Int64(contentLengthString) + if contentLength != this.cacheWriter.BodySize() { + this.isOk = false + _ = this.cacheWriter.Discard() + } } }