13 HTTP中的缓存
HTTP典型应用于能通过采用缓存技术而提高性能的分布式信息系统.HTTP/1.1协议包括的许多元素都尽可能的进行缓存操作.因为这些元素与协议的其 他方面有着千丝万缕的联系,而且他们相互作用、影响.因此,独立于算法、报头、响应代码等的细节描述来讲述HTTP中缓存的基本设计是大有裨益的.
如果不对缓存技术做明显改善,他将一无用处.HTTP/1.1中缓存的目的是降低在众多情况下发送请求的需要,同时降低在其他情况下发送完整响应的需要. 前者使众多操作中往返流程减少,我们用"过期" 机制来达到这一目的(见13.2节);
后者使网络带宽需求降低,我们用"认证"机制来达到这一目的(见13.3节). 对性能,可用性和分离操作的需要要求我们能放宽语义透明度的要求.HTTP1.1协议允许源服务器,缓存和代理客户在必要时明确降低透明度.然而,因为不 透明操作会迷惑不专业的用户,而且可能同某些服务器应用不兼容(如).在下列情况下,协议需要透明度被降低:
- 仅当代理或源服务器提出明确的协议层次的放宽请求.
- 仅当缓存或代理向终端用户提出明确的放宽警告.
因此,HTTP1.1协议满足如下要素:
- 当各部分都提出要求时,协议提供完全的语义透明度.
- 协议允许源服务器或用户代理明确请求且控制不透明操作.
- 协议允许缓存对未达到要求的语义透明度的响应发出警告. 说明:服务器,缓存,或代理设备可能面临的设计决策不在本说明书讨论范围之内.如果有关于语义透明度的决策,此设备应尽力保持语义透明度除非有仔细而完整 的分析表明破坏 透明度将有重大好处.
13.1.1缓存 正确性
在如下列情况下,一个正确的缓存必须从他所存储的内容中选出最新者来响应请求. (参见13.2.5,13.2.6,13.12节) 1. 经过检验,源服务器对收到响应重新确认生效返回的结果与原来相同.(参见13.3节) 2.."足够保鲜"(参见13.2节).在缺省值情况下,它表示对代理,源服务器和缓存 的最低的保鲜性要求(参见14.9节);如果源服务器详细说明,那么保鲜性要求仅是对源服务器本身而言有效.如果某一存储的响应对代理和源服务器的最低保 鲜要求仍不满足,慎重考虑,缓存应返回响应并加入适当警告报头(参见13.1.5,14.46节),除非这种响应是被禁止的(参见14.9节). 3. 304(未修改),305(代理人重寄),或 错误(4xx,5xx)响应信息. 如果缓存无法与源服务器通信,则当响应能正确的从缓存发出时,缓存应 如上响应;如果不能,则缓存应发出错误或警告信息以说明存在通信故障. 如果缓存收到响应(不论是一个完整响应还是一个304响应),它会将其转寄 给请求客户,当收到的响应被刷新时,缓存应该转寄给请求客户而不须加入新的警告 信息(且无需去掉已经存在的警告报头).缓存不能仅仅因为某一响应在传送过程中 "过时"了而令响应重新生效,这将引入一个死循环.一个用户代理收到没有警告的过 时响应应对用户显示警告.
13.1.2 警告信息
当缓存器返回响应既不是第一手的也不是最保鲜(fresh)的,此响应必须附加警告, 使用一般警告报头.此警告报头信息和刚刚定义的警告在14.46中有详述,此警告允许 客户采取适当行动. 警告信息可以被用作他途,不论是否与缓存有关.警告的使用,而非错误状 态代码区分了前述响应和实际错误. 警告信息由三类阿拉伯数字代码表示.第一个数字表明当重发成功后警告信 息是否必须或必须不被删除. See section 14.46 for the definitions of the codes themselves. 1xx 这是描述响应刷新或重发状态的警告信息,因此在重发成后功必须被删除掉 1xx警告信息仅当确认一个缓存实体时才由缓存器产生.它不能由代理端产生. 2xx 一个描述实体内容或报头的警告信息,它不因重新确认而被矫正,而且在成功的 重新确认后也不能被删除. 代码定义见14.46 HTTP1.0 缓存器存储响应中的所有警告信息,且不会删除第一类警告. 传给HTTP1.0的警告信息带有一个附加的警告数据区,它阻碍了未来的HTTP1.1兼 容错误缓存警告. 警告信息也传送一个警告文本.此文本可以使用任何自然语言,而且可以 随意选择准用的字符. 响应可以附加多重警告,包括属于同一类代号的警告.例如,服务器可能 提供同样的错误而文本包括英语和巴斯克语两种. 当响应附加了多重警告信息时,把所有的信息都显示给用户是不合理的 也是不现实的.此版本的HTTP并未指定严格规定警告显示的优先权和顺序,但却 给出了一些提示.
13.1.3 缓存控制机制
在HTTP1.1协议中的基本缓存机制是隐含指示给缓存器.在某些情况下, 一服务器或代理可能需要给缓存器以明确的指示,我们用缓存器控制报头来达到 这一目的. 缓存器控制报头允许代理或服务器传送多种指示,既可以是请求,也可 以是响应.这些指示代替缺省的缓存算法.作为一般规律,当出现明显的报头内 容冲突时,最根本的协调办法是实用性原则(即为,选择能最好保持予以透明度 的报头),可是,在某些情况下,缓存控制指示明显的削弱了语义透明度. 缓存器控制指示详述于14.9节
13.1.4直接的用户代理警告
很多用户代理允许用户覆盖基本缓存机制.例如,用户代理可能允许用户 指定缓存实体是无效的.或者,用户代理还可能习惯于加上缓存控制:对任何请 求最大值=3600.用户代理不应该默许非透明的行为或造成明显低效率的行为,但 可以由用户的明确行动来外在配置. 如果用户已经覆盖了基本缓存机制,用户代理应向用户明确指出,一旦 此改变作用于信息显示,可能与透明度要求发生冲突.协议通常允许用户代理来 决定响应是否已经失效,当实际发生时,该指示需要单独显示.该指示不必是对 话框,它可以是一个图标. 如果用户对缓存机制的覆盖使缓存器效率反常降低,用户代理应连续的 将这一状态提示给用户以防止用户无意中占用了额外资源或面临过长的延迟.
13.1.5 规则和警告的例外情况
在某些情况下,缓存操作员会选择设置缓存当用户未提出请求时发出过时 的响应.这一决定不应草率作出,但有时为了提高性能,尤其当缓存与源服务器 不良连接时,又是必须的.一旦缓存器返回一个失效的响应,这一定标明(使用 警告报头)令代理端软件生效来警告用户,可能存在潜在的问题. 协议还允许用户代理采取措施来获得第一手的或最新的响应.因此, 如果用户代理明确请求第一手的或最新的,缓存器不能返回过时响应,除非由于 技术上或政策上的原因而无法实现.
13.1.6 由客户控制的行为
当源服务器是满期信息的最初来源,在某些情况下,客户将需要控制 缓存器决定是否回复缓存的响应而不使其生效.客户需要使用缓存器控制报头的 几项指示来作此工作. 一个客户的请求可以指定它能接受的未确认响应的最长时限;指定一个 零点控制确认所有响应.一客户还可以指定响应期满前的最小时限.所有这些操 作增强了对缓存行为的控制,所以将不能放宽缓存器的语义透明度. 一客户也可以指定它接受失效响应,直到达到最大值.这放松了对缓存 器的控制,也就可能与源服务器对语义透明度的限制发生冲突.但对不良连接 时支持分离操作和提高性能来说又是必须的.
13.2 过期(Expiration)模型
13.2.1 服务器指定模型
当缓存器能完全避免向源服务器发送请求时,它工作于最佳状态. 避免请求的根本机制是源服务器给出一个明确的未来过期时间,这样响应信 息或许可以满足后来的请求.换句话说,缓存器不必首先联系服务器就能回复 一个最新响应. 我们期望服务器能指定一个对响应的明确预期过期时间,以确保在到达期 限之前,实体没有发生变化.当过期时间仔细选择时,这通常可以保持语义透明度. 此过期机制仅应用于缓存器作出的响应,而不针对直接传递给请求客户的 第一手响应. 如果一源服务器要强制一个语义透明的缓存器来确认每一个请求,它可 以指定一个明确的已过去过期时间.这表明响应总是失时效的,因此缓存器应在用 其答复后来的请求之前确认之.(见14.9.4) 如果源服务器想强制HTTP1.1缓存器无论如何配置都确认每条请求,则应 该使用"必须再确认"缓存器控制指示.(见14.9) 服务器指定明确的过期时间既可以使用过期报头,也可以使用最大期限(Max_age) 报头. 过期时间不能用来强制用户代理刷新其显示或重载其资源;它只应用于缓 存机制,当一个对某资源的新请求发出时,此机制仅须检测该资源的过期状态. (见13.13)
13.2.2 启发式过期
由于源服务器并不总是提供明确的过期时间,HTTP缓存器典型设置为启发 式过期时间,采取使用其他报头值的算法来估计一个近似的过期时间.HTTP1.1说明 书中并未给出详细算法,但却利用最坏情况来限制其结果.由于启发式过期次数可 能影响语义透明度,故应慎重使用,而且我们鼓励源服务器提供尽可能大的过期 次数.
13.2.3 年龄(Age)计算
为了解缓存实体是否为最新,缓存器需要知道其年龄是否已超过保鲜时 限.我们在13.2.4节中讨论如何计算后者,本节讨论如何计算响应或缓存实体的 年龄. 在此讨论中我们用“NOW”来表示“主机进行计算时时钟的当前值”. 使用HTTP协议的主机,除了运行源服务器和缓存器的主机,应当使用NTP[28] 或其他类似协议来将其时钟同步到一个全球性的精确时间标准上来. HTTP1.1协议要求源服务器尽可能在发送每条响应时都附加一个日期 报头来标明此响应产生的时间.(见14.18)我们用"日期值"这一短语来表示日期报 头的值----一种适于算术操作的形式. 当从缓存获得响应消息时,HTTP1.1用年龄响应报头来传达其年龄信息. 年龄值是缓存器估计的源服务器生成或重新确认响应的时间值. 本质上,年龄值是响应信息在从源服务器开始的所有缓存器驻留的时间 加上其在网络路径上传输的时间. 我们用年龄值("age_value")来标明年龄报头的值----一种适于算术操作的表示方法. 一个人的年龄可以通过两种完全独立的途径来计算: 1.如果本地时钟与源服务器时钟同步的相当好,则用"NOW"-日期值,若结果 为负,则取零. 2.如果从源服务器开始的所有缓存器均执行HTTP1.1则就取年龄值(age_value). 如上我们有两种方法计算响应的年龄,我们合并二者如下: 矫正后接收到的年龄值=MAX(NOW-DATA_VALUE,AGE_VALUE) 而且无论那种方法都能得到可靠的结果. 由于网络附加延时,一些重要时隙会在服务器产生响应和下一个缓存器或客 户收到它之间被忽略.如果不经修订,这一延迟会带来不正常的低年龄. corrected_initial_age = corrected_received_age + (now - request_time) 因为导致返回年龄值的请求一定在年龄值的产生之前就发出了,我们可以 通过记录请求发出的时间来矫正网络附加延时.则当收到一个年龄值时,它必将被 认为与发出请求的时间有关,而不是收到响应的时间.这将保证不论经历多少延时, 其表现都是稳定的. 当缓存收到响应时的算法摘要: /* * age_value * is the value of Age: header received by the cache with * this response. * date_value * is the value of the origin server's Date: header * request_time * is the (local) time when the cache made the request * that resulted in this cached response * response_time * is the (local) time when the cache received the * response * now * is the current (local) time */ apparent_age = max(0, response_time - date_value); corrected_received_age = max(apparent_age, age_value); response_delay = response_time - request_time; corrected_initial_age = corrected_received_age + response_delay; resident_time = now - response_time; current_age = corrected_initial_age + resident_time; 以上段落英文更明白一些. 缓存实体的当前年龄是从缓存实体最后被服务器确认的时间(以秒记) 加上校正初始年龄.当缓存实体产生一条响应,它必须包含一个年龄报头区:与缓 存实体当前年龄一样的值. 响应中存在年龄报头区意味着这不是第一手响应.但反之未必,因为那仅 当所有缓存器均使用HTTP1.1时才成立.
13.2.4 过期计算:
为了确定一条响应是新是旧,我们需要将其保鲜期限和年龄进行比较,年龄的计算见13.2.3节,本节讲解怎样计算保鲜期限,以及一条响应是否已经被排出. 在下面的讨论中,数值可以用任何适于算术操作的形式表示. 我们用“过期数值”("expires_value")来标明过期报头,我们用“最大年龄值”来标明缓存控制报头的秒数.(question?) 最大年龄在过期之前指示,所以一旦响应中出现最大年龄,计算将变得非常简单. freshness_lifetime = max_age_value 否则,若缓存中出现“Expires”,计算如下: freshness_lifetime = expires_value - date_value 注意上述运算不受时钟误差影响,因为所有信息均来自源服务器. 如果 Expires, 缓存控制: max-age, 或 缓存控制: s-maxage (见 14.9.3) 均未在响应中出现,且响应对缓存没有其他限制,缓存可以用启发式算法计算freshness lifetime.缓存器必须对年龄大于24小时又不带警告的响应附加113号警告. 而且,如果响应有最后修改时间,启发式过期值应不大于时间片.典型设置为片断的10% 计算响应是否过期非常简单: response_is_fresh = (freshness_lifetime > current_age)
13.2.5 澄清过期值
由于过期值不是严格制定的,所以可能两个缓存器对相同资源制定的刷新值不同. 如果客户对一个在其缓存中以刷新的请求作出一个恢复的非第一手响应,而且缓存实体中的日期值比响应中的新.,则客户可以忽略此响应.如果这样,将要求“缓 存控制”:max-age=0 来强迫检查源服务器. 如果缓存器有两个描述相同而确认器不同的响应,它必须使用有最近日期报头的那个.
13.2.6 澄清多重响应
因为客户可能收到经多重路径来的响应,所以有些响应流经一簇缓存器,而另一些响应流经另一簇缓存器,客户收到响应的顺序可能与源服务器发响应的顺序不同, 我们希望客户能选用最新的响应. 实体标签和过期值都不能影响响应顺序,晚一点的响应可能带有早的过期时间.日期值的精度也只有一秒. 当缓存器要重新确认一个缓存实体,而且受到响应的日期报头晚于已存在的实体,则客户应无条件的重复请求. Cache-Control: max-age=0 强制任何中间缓存器确认它们的副本. Cache-Control: no-cache 或者强制它们从源服务器获取一个新的副本. 如果日期值相同,可以使用任何一个响应.
13.3 确认模式
当缓存器想要用一个失时效的条目来相应客户的请求,他首先必须向源 服务器(如果可能则向一中间缓存器)检验这一缓存条目是否仍然可用.我们称之为 "确认"缓存条目.由于我们不想当缓存条目为可用时必须为再传送整条响应而付出 代价,而且不想当缓存条目不可用时也必须多传一圈,HTTP1.1协议支持使用条件反应方法. 协议支持条件响应方法的关键特征围绕"缓存确认器"展开.当源服务器 生成一个完整响应时,它同时传送一类确认器一直伴随着缓存条目.当一客户(用户 代理或代理缓存器)对含有缓存条目的资源做出条件请求时,他同时在请求中包含有相互关联的确认器. 服务器则核对此确认器和当前确认器,如果他们匹配(见13.3.3),则返回 一个特定状态码(通常为304)且不含条目内容.否则,返回整个响应(包含条目内容) 这样,我们避免了在确认器匹配时传送整条响应,同时也避免了在不匹配时往返传输. 在HTTP1.1协议中,一个条件请求除了带有特别的报头(包含确认器)来暗中 的将它转入条件算法以外,和普通报头没有差别. 协议中包括缓存确认机制的主动和被动两种状态.具体说来,请求可以在 当且仅当又匹配确认时执行,也可以在当且仅当没有匹配确认时执行. 说明:没有确认器的响应也可以缓冲存储且接受服务直至被排出,除非这是 被缓存控制指令明确禁止的.可是,如果没有确认器,则缓存不能有条件的恢复它,这表明无法刷新除非被排出.
13.3.1 最后修改日期 (Last-Modified Dates)
最后修改报头值经常被用作确认器.简言之,一缓存条目在最后修改期后 未经修改则被认为是有效的.
13.3.2 标签缓存确认器(Entity Tag Cache Validators)
标签响应报头值,一个实体标签,提供了一个"模糊"缓存确认器.这将允许 在不便存储修改信息的情况下进行可靠的确认,包括HTTP日期数据不充足和源服 务器不想因使用修改日期而带来麻烦的情况. 实体标签描述见3.11节,有关其报头的描述见14.19,14.24,14.26,14.44.
13.3.3 强,弱确认器
由于源服务器和缓存器会比较两个确认器来确定他们是否代表相同的条目,所以通常希望实体发生任何变化,确认器也相应变化,这样的确认器为强确认器. 同时还会有这样的情况,服务器倾向于仅在发生重要的语义变化时才改变确认器.在资源变化时确认器未必变化的称为弱确认器. 实体标签通常是强确认,但协议提供一种机制来标志弱 Copyright www.cnpaf.net (2007). All Rights Reserved. 确认.可以认为,强确认在实体的每一字节变化时均变化,而弱确认仅在实体含义变化时才变化,强确认是某一特定实体的标志,而弱确认是某一类同义实体的标 志. 注: 强确认的例子:一个整数,他随着每次实体发生变化而定值增长. 一个实体的修改时间(以秒计算)可以作为弱确认器,因为实体可能在一秒内变化两次. 对弱确认的支持是可选的.支持弱确认可带来等价体的高效缓存. 当客户生成一个在确认报头中包含确认器的请求或服务器进行比较时均要用到确认器. 强确认可在任何情况下使用,而弱确认仅在不依赖严格相等时才可用. 客户可以发出简单GET请求,伴随强,弱确认器均可.客户在发其他请求时,不能用弱确认. HTTP1.1协议定义确认的唯一功能是比较.有两种比较功能,这依赖于是否允许弱确认. -- 为了同等考虑,两确认器必须完全一样且均非弱确认. -- 两确认器必须完全相同,且至少有一个被标明为"弱". 除非被明确标清,实体标签是强的. 最后修改时间被用作请求的确认器时默认为弱的,除非从下列规则导出强的结论. 确认器不会在一秒内变化两次. 或者 -确认器可能被用户用于If-Modified-Since 或者 If-Unmodified-Since报头. -此缓存实体包含一日期值,他给出源服务器发出响应的时间. -最后修改时间至少比日期值早六十秒. 或者 -确认器已经被中间缓存器同缓存实体比较过 -此缓存实体包含日期值,给出源服务器发出响应的时间. -最后修改时间至少比日期值早六十秒. 此种方法基于以下事实:如果两条响应在同一秒内被发出但有相同的最后修改时间,则至少有一条响应日期值和最后修改时间是相同的. 如果客户在仅有最后修改时间没有模糊确认器的情况下执行子范围修复, 则仅当最后修改时间是强确认时才可以. 若缓存器或源服务器收到一个条件请求,而不是完整GET响应,则必须使用强比较函数. 此规定允许HTTP1.1协议下,缓存器和客户可以对从HTTP1.0中得到的值安全的进行子域恢复.
13.3.4 关于何时使用实体标签和最后修改时间的规则
我们对源服务器,客户和缓存器采用一套规则和建议来规定在何时,出 于何种目的,应采用何种确认器. HTTP/1.1 源服务器: -应该发送一实体标签除非它做不到. -可以发送弱实体标签如果其满足性能要求或不能发送强确认. 换句话说,对http1.1服务器来说,比较好的做法是同时发送强实体标签和最后修改值. 说明:为保证语义透明缓存,服务器必须避免两个不同实体重复利用同一 强实体标签值或者两类不同语义的实体重复使用同一弱实体标签值. HTTP/1.1 客户: -若服务器用实体标签,则必须对任何缓存条件请求都使用此实体标签. -仅当服务器提供最后修改值时,它应该在非子域条件请求中使用该值. -仅当HTTP1.0服务器提供了最后修改值时,他可以在子域缓存条件请求 中使用该值. -若两者均被提供,则两者均应使用. 当一服务器收到的请求既包括最后修改时间也包括一个或多个实体标签, 则它一定不能发出304代码,除非这是协调好的. 当一个HTTP1.1缓存代理收到上述请求时,一定不能返回一个本地缓存响 应给客户,除非它对所有请求都是一致的. 说明:一般规律是传送尽量多的非冗余信息. HTTP1.0客户和缓存器忽略实体标签. 13.3.5 不确认条件 其他报头的比较不被用于确认缓存实体.
13.4 缓存能力响应
除非被明确限制,缓存系统可以将一成功的响应作为缓存实体一直存储,如果它是保鲜的可以不确认而返回它,如果成功确认,也可以返回它. 说明:某些HTTP1.0缓存器可能违反这一条而不提示警告. 还有,某些情况下可能不便保留一实体,或将其返回给后续请求. 注意14.8节防止共享缓存存储和回复一个早先的包含授权报头的请求. 包含状态码200,203,206,300,301或410的响应可能会被用于回复后面的响应. 带有其他一些状态码的响应不能用于回复后面的请求,除非有明确的缓存控制 或其他报头允许之.
13.5 从缓存器构造响应
缓存器的目的是存储响应请求的信息来响应后面的请求.再很多情况下,缓 存器仅返回响应的适当部分给请求者.如果缓存器保有一个基于前面请求的实体,它 可能必须将其与新响应合并.
13.5.1 端到端和Hop-by-hop报头
为定义缓存器行为,我们将报头分成两类: 端到端报头和hop_by_hop报头(仅对简单的传输层连接有意义,不被缓存, 也不被代理服务器向前传递) hop-by-hop 报头: - Connection 连接 - Keep-Alive 保活 - Proxy-Authenticate 代理人鉴别 - Proxy-Authorization 代理人授权 - TE - Trailers 轨迹 - Transfer-Encoding 传输编码 - Upgrade 升级 所有其他均为端到端报头
13.5.2 不可更改报头
HTTP1.1的某些特征,如分类鉴定,基于某一端到端报头值.一透明代理不能 修改端到端报头除非报头要求或明确许可. 传输代理不能修改下列各项,如果他们不存在,也不能添加. - Contents location 目录区 - Content-MD5 - ETag - Last-Modified 最后修改时间 - Expires 但它可以添加这些区域.如果排除报头被添加,则必须赋值来标明次响应的 日期报头. 包括不变形缓存控制指示或有请求. - Content-Encoding 内容编码 - Content-Range 内容区 - Content-Type 内容类型 警告:对端到端报头的不必要修改可能导致在今后高版本协议引入更强的鉴 定机制后鉴定失败 内容长度区的去留规则见4.4节.
13.5.3 联合报头(Combining Headers)
当缓存向服务器发出确认请求,若服务器回复304或206响应,则缓存器构 造响应回复给请求客户. 若状态码为304,则缓存器使用缓存实体的报文构造响应,若状态码为206 且标签和最后修改时间恰好匹配,则缓存器可以将存储的和刚收到的实体和并作为 新响应的报文(见 13.5.4). 缓存实体中的端到端报头用于构造响应,排除以下内容: -1xx警告报头被删除 -2xx保留 -304或206响应中的报头代替缓存实体中的相应部分. 除非要删除缓存实体,缓存器必须用收到的响应报头取代端到端报头.换句话说, 接收到的端到端报头覆盖缓存实体中已有的端到端报头. 注意:此规则允许源服务器用304或206响应来刷新缓存器中的相应实体.
13.5.4 联合字节范围
一条响应可能仅传送一条正文的一部分,经过几次这种传送,一缓存器可能会 收到同一条正文的好几部分. 如果缓存器已经收到正文的一部分,且又收到了另一部分,缓存器可以 将新收到的内容与已有内容合并,当所有收到的响应及缓存实体含有强确认时.
13.6 缓存谈判响应
使用服务器驱动内容转让(见12.1),由响应中的变化报头区说明, 改变了缓存器能用响应回复后续请求的条件和过程.(服务器使用变化报头区见14.44) 服务器要用变化报头区告知缓存器在众多可缓存响应类型用什么样的请求 报头区来用服务器驱动转让.变化区命名此类报头区为"选择"请求报头. 当缓存器收到指定一个或更多包含变化报头区的缓存实体的后续请求,缓存器不能用这样的缓存实体来构造新请求的响应,除非新请求中所有选中的请求报头与初始请求相应部分匹配. 当且仅当两个请求中的选择请求报头可以从前一请求变形为后一请求时称为匹配.变形指,在相应的BNF允许的位置增加或删除LWS,或者按照4.2节中的消息报头规则合并合并同名的多个消息报头区. 一个变化报头区数值"*"一般不能匹配而且对该资源的后续请求,服务器只能粗略解释. 如果旧的请求报头不能匹配新的,缓存器不能用相应缓存实体来回复响应 除非它第一个将请求发给服务器且服务器回复304,包括实体标签或内容地址说明 实体可用. 如果一实体标签用于标志缓存的代表,向前传递的请求应该是条件的且包 括实体标签.这给服务器揭示了缓存器刚刚缓存的所有实体,所以如果其中任何实体与请求实体匹配,服务器可以用304响应中的ETag报头区来稿置缓存实体可达.如果新请求中的实体标签与已存在实体匹配,则新响应应该用于刷新存在实体的报头区, 并将结果返回给客户. 如果任何已存在缓存实体仅包括相关实体的部分内容,它的实体标签不能 包含于If-None-Match报头区中, 除非此请求是对一个被该实体完全满足的区域. 如果缓存器收到一个成功响应,已存在实体不能回复将来的响应且应该被删除.
13.7 共享和非共享缓存
出于安全和保密考虑,有必要区分共享和非共享缓存.非共享缓存是仅 供一个用户使用的缓存器,此种情况下,可用性由适当的安全机制控制.其它缓 存器均被认为是共享缓存.此协议的其它部分给出了其它的一些限制以防止隐私 的丢失和可达控制的失败.
13.8 错误和不完全响应缓存行为
缓存器收到不完整响应时也可以存储它,但是必须把它看作部分响应. 部分相应可以合并(见13.5.4);合并结果可能是完整的或仍是部分的.缓存器 不能把部分相应回复给客户,除非有明确要求. 如果缓存器在试图重新确认一实体时收到5xx响应,它既可以将其传送给 客户也可以认为服务器响应失败.后一种情况,它可以回复一个以前接收到的响应 除非缓存实体明确要求“必须确认”
13.9 GET 和 HEAD 的副作用:
除非服务器明确禁止缓存它们的响应,对任何资源应用GET和HEAD算法, 如果响应曲子缓存器,都不会引起能导致错误的副作用.他们确实有副作用,但 缓存器在决定缓存时不必考虑.缓存器总是“看源服务器的脸色行事”. 一个例外:有些应用习惯于在query URLs时使用GET和HEAD,从而带来显著的副作用, 缓存器不能认为对他们的响应是刷新的,除非服务器明确给出过期时间.这说明不能 从缓存器取出HTTP1.0服务器对URIs的响应.
13.10 刷新或删除后的无效性
某些算法对源服务器资源的操作将使一个或多个已存在的缓存实体不可 用,即为,虽然他们还是“新鲜”的,但却不能准确反映源服务器想回复给请求 的信息. HTTP协议无法保证所有此类实体均被标明无效.例如,引起源服务器变 化的请求可能没到达存贮缓存实体的代理服务器,但是,有一些规则帮助减少类 似的错误. 本节中,“使一个实体失效”表示缓存器或者删除该实体的所有instances,或者标明其为不可用,而且在重新用于回复后面的响应前必须有重新确认命令. 某些HTTP算法必将导致缓存器使一个实体失效.这是实体被URI请求或内 容区域报头提到.这些算法是: - PUT - DELETE - POST 为了防止服务器拒绝处理,基于URI或内容区域报头的失效处理仅当主机 部分与URI请求相同时才进行. 缓存器向它不理解的算法传递请求时令所有被URI请求指明的实体失效.
13.11 强制写通过( Write-Through)
所有可能对源服务器资源进行修改的算法都要写给源服务器.这通常包括 所有算法除了GET和HEAD.缓存在将此种请求转给内地服务器并获得相应答复前不 能对请求客户做出响应. 相反情况(write-back)在HTTP1.1中是不允许的,这是由于提供一致更新 非常困难且服务器缓存和网络的故障比“write-back”早.
13.12 缓存替换
如果收到一个新的响应,它的同源响应均已被缓存,缓存器就要用新响应 回复当前请求,且将其插入缓存器存储区,并用其回复所有被退回的旧响应. 说明:一个日期报头比已存响应旧的新响应是不可缓存的.
13.13 历史纪录
用户代理经常使用历史体制来重新获得以前的实体. 历史机制和缓存是不同的,尤其历史对资源的当前状态是不透明的,更准 确地说就是历史纪录明示用户在获得资源时看到了什么. 默认情况,过期时间不用在历史机制中.若实体仍然在存,即使它过期 历史机制仍可以显示它,除非用户明确提出要代理刷新过期纪录. 这并不能解释为禁止历史体制告诉用户事情已经过时. 说明:如果历史纪录未必阻止用户看过时资源,这将强制服务提供者避免 使用HTTP过期控制和缓存控制.


0 Responses to "HTTP超文本传输协议-HTTP/1.1[13.HTTP中的缓存]"
发表评论