2.2.2. Comparison
这一小节主要描述在满足一定条件以后,Last-Modified可以作为强验证器使用。
判断Last-Modified是强/弱验证器的前提
A Last-Modified time, when used as a validator in a request, is
implicitly weak unless it is possible to deduce that it is strong,
using the following rules:
注意!“when used as a validator in a request”表明只有当Last-Modified作为request中的validator时,才有能对其进行强/弱验证器的判断。
当满足如下条件时可以作为强验证器
o The validator is being compared by an origin server to the actual
current validator for the representation and,
o That origin server reliably knows that the associated
representation did not change twice during the second covered by
the presented validator.
or
o The validator is about to be used by a client in an
If-Modified-Since, If-Unmodified-Since, or If-Range header field,
because the client has a cache entry for the associated
representation, and
o That cache entry includes a Date value, which gives the time when
the origin server sent the original response, and
o The presented Last-Modified time is at least 60 seconds before the
Date value.
or
o The validator is being compared by an intermediate cache to the
validator stored in its cache entry for the representation, and
o That cache entry includes a Date value, which gives the time when
the origin server sent the original response, and
o The presented Last-Modified time is at least 60 seconds before the
Date value.
一共3个情况,每个情况的第一条描述了谁来用哪2个validator来进行对比。
Last-Modified精确到秒导致的问题
注意,在本节讨论中:
- t(x)表示动作x的精确时刻t
- truncate_t(x)表示动作x所在的秒数
问题
//注,两根“===”分别表示某一秒的开始和结束
=========
modify_1
response_x
modify_2
=========
- modify_1/modify_2落在同一秒内,由于Last-Modified精确到秒,导致他们数值一致
- modify_1/modify_2中间有一个或者多个response_x
- "==="之间表示在同一秒内
当 modify_2 以后,这些 response_x 如果去发起 If-Modified-Since,这时:
- request_x:t(modify_1)
- server:对比发现truncate_t(modify_1) == truncate_t(modify_2)
- server:返回304
这是由于Last-Modified只能精确到秒导致的。
解决办法
如果两次modify没有落在同一秒就不会有这个问题,那么应该如何判断出这种情况呢?在执行顺序上天然的有:
modify_1
response_x
modify_2
显然,如果想让 modify_1/modify_2 落在不同秒,则至少需要:
- t(response_x) - t(modify_1) >= 1s
在不考虑其他因素时(例如时间同步问题),在这种前提下的Last-Modified不会出现由于精度为秒导致的问题,所以RFC将这种“前提”作为Last-Modified成为强验证器的条件之一。
TODO:这里的理解感觉理解的比较仓促
60s
The arbitrary
60-second limit guards against the possibility that the Date and
Last-Modified values are generated from different clocks or at
somewhat different times during the preparation of the response. An
implementation MAY use a value larger than 60 seconds, if it is
believed that 60 seconds is too short.
根据上一节的讨论,理论上避免精度问题需要:
- t(response_x) - t(modify_1) >= 1s
RFC说考虑到不同时钟之间的差距,选择60作为差值,实现也可以自己选择。TODO:不是很理解。
节选解释
This method relies on the fact that if two different responses were
sent by the origin server during the same second, but both had the
same Last-Modified time, then at least one of those responses would
have a Date value equal to its Last-Modified time.
前置:
- modify_1/response_1
- modify_2/response_2
条件:
- two different responses
- during the same second
- had the same Last-Modified time
结论:
- at least one of those responses would have a Date value equal to its Last-Modified time
分析:
"different responses" 指的是“对应不同的representation的response”,并不是指“相同representation,但是发送了2次response”
// 注
// 假设指“相同representation,但是发送了2次response”
// "---"线之间为1s
modify_1
....过去了10分钟
------------
response_1
....
response_2
------------
显然,date(response_1)/date(response_2)与truncate_t(modify_1)不想等,推不出rfc中所指的结论.
"had the same Last-Modified time" 指的是:
- truncate_t(modify_1) == truncate_t(modify_2)
- 并不是指同一时刻!
根据条件有以下两种结果:
//注
//"==="线之间为1s,并且恰好,表示某一秒的开始和结束。
//"---"线之间为1s
//情况1:
=============
modify_1
-------------
response_1
modify_2
=============
response_2
-------------
//情况2:
=============
modify_1
-------------
response_1
modify_2
rresponse_2
-------------
=============
情况1:
- truncate_t(modify_1) == truncate_t(response_1)
- truncate_t(modify_2) != truncate_t(response_2)
情况2:
- truncate_t(modify_1) == truncate_t(response_1)
- truncate_t(modify_2) == truncate_t(response_2)
"have a Date value equal to its Last-Modified time" 指的是精确时刻取整为秒以后的相等。
"at least one of " 指的是,在RFC定下的条件下,情况1中有1个“相等”,情况2中有2个“相等”。