預期行為:
If-None-Match
If-None-Match
與 結合使用時優先If-Modified-Since
。
checkNotModified
該函式org.springframework.web.context.request.ServletWebRequest
甚至參考了預期的優先順序,并帶有以下注釋:
// Evaluate conditions in order of precedence.
// See https://tools.ietf.org/html/rfc7232#section-6
觀察到的行為
當從指示資源未被修改NOT MODIFIED
時checkNotModified
呼叫時handleRequest
,回應將更新狀態。org.springframework.web.servlet.resource.ResourceHttpRequestHandler
lastModifiedTimestamp
當使用指示資源已修改的 etag 值從in呼叫時,不會再次更新回應。checkNotModified
updateResponse
org.springframework.web.filter.ShallowEtagHeaderFilter
因此,當設定了和 -標頭304 NOT MODIFIED
時,服務器會回傳無效的 etag 。If-None-Match
If-Modified-Since
問題
回滾到較早的部署后,客戶端將發送比服務器上的內容更新的 lastModifiedTimestamp 和無效的 etag。由于If-None-Match
沒有預期的優先級,因此客戶端在預期 a304 NOT MODIFIED
時收到 a 200 OK
。
解決方法
問題可以通過不使用來緩解If-Modified-Since
。例如利用setUseLastModified(false)
資源處理程式。
再生產
發送GET
帶有無效 etag 的 -request 并lastModifiedTimestamp
在未來發送。
問題
Spring是否正確處理和的組合If-Modified-Since
,If-None-Match
或者這可能是一個錯誤?
更新 1
(感謝凱文)
這似乎是我的問題,因為本地和 spring-project 中的實作細節不同。
- 我不匹配主分支和 5.3.x 分支。本地實作與5.3.x 分支上的實作相匹配。
更新 2
checkNotModified
被測驗覆寫IfNoneMatchAndIfNotModifiedSinceShouldNotMatchWhenDifferentETag
。但是,此測驗涵蓋同時使用和checkNotModified
呼叫的情況。在所描述的情況下,通過多載方法順序呼叫。多載的方法呼叫將回應狀態更改為. 這似乎沒有由 ShallowEtagHeaderFilter 處理,其中isEligbleForEtag如果狀態代碼為,則回傳 false ,并且如果 etag 已更改,則來自shallowEtagHeaderFilter 中的 updateResponse的呼叫不會更新來自to的回應。 eTag
lastModifiedTimestamp
checkNotModified
lastModifiedTimestamp
304 Not Modified
304
checkNotModified
304
200 OK
更新 3
錯誤報告
更新 4
我在這里添加了一個簡單的復制器。這是一個干凈的 Spring 啟動器,具有 Spring Web 依賴項、一個 HTML 檔案和啟用的淺 etag 過濾器。
打開 http://localhost:8080/index.html 應該在回應頭中ETag
提供必要的值。Last-Modified
預期行為
發送ETag
值設定為的 curl 請求,設定為If-None-Match
,按預期回傳。Last-Modified
If-Modified-Since
304 Not Modified
如果您修改If-Modified-Since
為及時回傳,您將收到200 OK
預期的結果。
意外行為
但是,如果您只修改該ETag
值,即快取內容的 ETag 與服務器上計算的 ETag 不同,您期望得到200 OK
. 但是,你會得到一個304 Not Modified
出乎意料的結果,因為當與 結合使用時If-None-Match
具有優先級。優先級記錄在https://tools.ietf.org/html/rfc7232#section-6中,在checkNotModified中參考,并且似乎已被https://www.rfc-editor.org/rfc/rfc9110#section-13.2.2廢棄.If-None-Match
If-Modified-Since
卷曲
(記得替換標題值)
curl --location --request GET 'http://localhost:8080/index.html' \
--header 'If-None-Match: "0c01d44fcb5bdfc18313ea8cb309217af"' \
--header 'If-Modified-Since: Sat, 27 Aug 2022 23:26:55 GMT'
問題
核心問題似乎是在checkNotModified
從in 呼叫org.springframework.web.filter.ShallowEtagHeaderFilter
狀態更新回應NOT MODIFIED
之前checkNotModified
呼叫handleRequest
inorg.springframework.web.servlet.resource.ResourceHttpRequestHandler
。
uj5u.com熱心網友回復:
您所描述的行為已被報告并據稱已修復。他們還有一個測驗用例,旨在捕獲您描述的確切情況(不ETag
匹配,并且 future last modified 應該回傳200
)IfNoneMatchAndIfNotModifiedSinceShouldNotMatchWhenDifferentETag
:。
但是,正如您所說,handleRequest
實際上并沒有checkNotModified
使用兩個引數進行呼叫。您會在當前版本的軟體上看到這種行為。
所以這聽起來像是一個真正的錯誤,我想說下一步是使用 Spring Framework 提交錯誤報告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/505296.html