10.7 过期(Expires)
过期实体标题域中的日期/时间值指定了实体过期的时间。这为信息提供方提供了使信息失效的手段。当超过此期限时,应用程序不应再对此实体进行缓存了。过期并不意味着原始资源会在此期限后发生改变或停止存在。在实际应用中,信息提供者通过检查过期标题域中所指定的时间,从而获知或预测资源将会发生改变的确切日期。该格式用的是绝对日期时间(3.2节)。
Expires = "Expires" ":" HTTP-date
例如:
Expires: Thu, 01 Dec 1994 16:00:00 GMT
如果给定日期比日期标题中的要早(或相同),接收方不应缓存附加的实体。如果资源是动态自然生成的,象有些大量数据的处理,资源的实体应当被加上一个适当的过期时间值。
过期域并不能强制用户代理对其进行刷新或重新载入资源,它只用于缓存机制。当对已初始化过的资源发出新请求时,该机制才检查该资源的过期状态。
用户代理通常都有历史记录机制,如“后退”按钮和历史记录列表。该种机制可以用来重新显示某次对话(session)之前已经获取的实体信息。在缺省状态下,过期域不对历史机制使用。除非用户在配置用户代理时指定了对历史文件进行过期刷新,否则,只要实体还保存着,历史机制就能显示它,不论该实体是否已经过期。
注意:应用程序应兼容对过期标题非法或错误的实现,如碰到0值或非法的日期格式,应用程序应将其视为“立即过期(expires immediately)”。虽然这些值不符合HTTP/1.0,对于一个健壮的应用来说,还是必要的。
Berners-Lee, et al Informational [Page 41]
10.8 来自(From)
From请求标题域,如果给出来,则应包括一个使用此用户代理的人类用户的Internet e-mail地址。该地址应当能被系统识别,就象RFC822[7](已经更新为RFC1123[6])中的邮箱定义一样。
From = "From" ":" mailbox
例如:
From: webmaster@w3.org
该标题域可能用来做为登录目的使用,以确定对某资源的请求是否合法。它不应用于不安全的访问保护。该域的解释是,请求已按请求人指定的行为方式完成,而该请求人将为此种方式负责。特殊情况下,机器人(robot)代理也应包括此标题域,域中注明是谁运行它的,这样,当接收端发生任何问题时,都可以同这个人取得联系。
该域中的Internet e-mail地址可以与处理该请求的Internet主机分离。例如,当请求通过代理(proxy)时,应使用原始的传输地址。
注意:客户端在没有得到用户批准时,不应发送From标题域,因为这样做可能会产生用户隐私及网站安全方面的问题。强烈建议在请求之前提供手段以禁止(disable)、允许(enable)、修改(modify)该域的值。
10.9 从何时更改(If-Modified-Since)
If-Modified-Since请求标题域和GET方法一起使用,用于处理下面情况:当在该域指定的日期以来,请求资源没有发生任何变更。这时,服务器将不会下传该资源的拷贝,即,回应不带任何实体主体,只是304状态码(未修改)。
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
例如:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Berners-Lee, et al Informational [Page 42]
条件GET方法可以请求服务端将在If-Modified-Since标题域中的指定日期后发生变更的指定资源下传,也就是说,如果资源没发生变化,就不下传了。其算法如下:
a) 如果请求的回应状态不是200(成功)码或它传过来的If-Modified-Since中的日期不合法,此时按照普通GET来回应。如果日期比服务器的当前时间还要晚,则是非法时间。
b) 如果资源在If-Modified-Since日期以后有变化,回应也和普通GET一样
c) 如果资源在If-Modified-Since日期以后没变化,服务器端将回应304(未修改)。注:该日期应是合法的。
这样做的目的是为了以最小的代价,对被缓存信息进行有效更新。
10.10 最近更改(Last-Modified)
Last-Modified实体标题域表示由发送方设定的资源最近修改日期及时间。该域的精确定义在于接收方如何去解释它:如果接收方已有此资源的拷贝,但此拷贝比Last-Modified域所指定的要旧,该拷贝就是过期的。
Last-Modified = "Last-Modified" ":" HTTP-date
例如:
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
该标题域的精确含义取决于发送方的执行方式及原始资源的自然状态。对于文件来说,可能是它在文件系统的last-modified时间。对于包含多个组成部分的实体来说,可能是组成部分中最新的last-modify时间。对数据库网关来说,可能是记录的last-update时间戳。对于虚(virtual)对象来说,可能是内部状态的最近改变时间。
原始服务器不应发送比服务器消息产生时间更晚的Last-Modified日期,因为该消息会导致服务器在未来的某个时间内,用消息原始的日期对该域值进行再次更新。
Berners-Lee, et al Informational [Page 43]
10.11 位置(Location)
Location回应标题域定义了由请求URI指定的资源的位置。对于3xx(重定向)回应,位置域必须能帮助服务器找到相应的URL,以实现对资源的重定向。只允许用绝对URL。
Location = "Location" ":" absoluteURI
例如:
Location: http://www.w3.org/hypertext/WWW/NewLocation.html
10.12 注解(Pragma)
Prama普通标题域包括一些可能对请求/回应链中的任一接收方有用的特殊指示信息。从协议角度看,所有的注解指示了一些特定的可选行为,事实上,一些系统可能会要求行为与指示一致。
Pragma = "Pragma" ":" 1#pragma-directive
pragma-directive = "no-cache" | extension-pragma
extension-pragma = token [ "=" word ]
当"no-cache"出现在请求消息中时,应用程序应当向原始服务器推送此请求,即使它已经在上次请求时已经缓存了一份拷贝。这样将保证客户端能接收到最权威的回应。它也用来在客户端发现其缓存中拷贝不可用或过期时,对拷贝进行强制刷新。
不管注解(Pragma)指示信息对代理(proxy)及网关(gateway)应用程序如何重要,它必须能穿越这些应用,因为该信息可能对请求/回应链上的其它接收方有用。实际上,如果注解与某个接收方无关,它应当被该接收方忽略。
10.13 提交方(Referer)
提交方请求标题域是出于服务器端利益方面的考虑,允许客户端指明该链接的出处,即该指向资源地址的请求URI是从哪里获得的。这样,服务器将产生一个备份链接(back-links)列表,用于维护受欢迎的资源、登录、缓存优化等活动。
Berners-Lee, et al Informational [Page 44]
Referer = "Referer" ":" ( absoluteURI | relativeURI )
例子:
Referer: http://www.w3.org/hypertext/DataSources/Overview.html
如果只给了部分URI,应当参照请求URI来解释它。URI不能包括段(fragment)。
注意:因为链接的原代码可能暴露一些隐私信息,因此强烈建议由用户来决定是否发送提交人域。例如,浏览器客户端有个选项可以用来进行离线浏览,可以使能或禁止提交人或表单信息的发送。
10.14 服务器(Server)
服务器回应标题域包含由原始服务器用来处理请求的软件信息。该域可包含多个产品标识(3.7节)及注释以标识服务器及重要的子产品。按照习惯,产品标识将按其应用的重要顺序排列。
Server = "Server" ":" 1*( product | comment )
例如:
Server: CERN/3.0 libwww/2.17
如果回应要通过代理来推送,代理应用程序不应将它自己的数据加入产品列表。
注意:一些指定服务器软件的版本有启示作用,因为这些版本的软件存在一些安全漏洞,将使服务器更易受到攻击。提倡服务器软件在实现时,将此域变成可以进行配置的选项。
Berners-Lee, et al Informational [Page 45]
注意:有些服务器不遵守服务器域产品标识的语法约束。
10.15 用户代理(User-Agent)
用户代理请求标题域包含用户原始请求的信息,这可用于统计方面的用途。通过跟踪协议冲突、自动识别用户代理以避免特殊用户代理的局限性,从而做到更好的回应。虽然没有规定,用户代理应当在请求中包括此域。该域可包含多个产品标识(3.7节)及注释以标识该代理及其重要的子产品。按照习惯,产品标识将按子产品对应用的重要性顺序排列。
User-Agent = "User-Agent" ":" 1*( product | comment )
例如:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
注意:现存有些代理应用将它们的产品信息回到了用户代理域中,这种方法不值得提倡,因为这样做会使机器在解释这些信息时产生混淆。
注意:现在有些客户端不遵守用户代理域中产品标识的语法约束。
10.16 WWW-授权(WWW-Authenticate)
WWW-授权回应标题域必须被包括在401(未授权)回应消息中。该域值由一个以上的challenge组成,这些challenge可用于指出请求URI的授权方案及参数。
WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge
HTTP访问授权处理在11节中描述。用户代理在解析WWW-授权域值时要特别注意看看它是否包含一个以上的待解决问题(challenge)或是否提供了一个以上的WWW-授权标题域,因为待解决问题(challenge)的内容中可能包含用逗号分隔的授权参数列表。
Berners-Lee, et al Informational [Page 46]
11. 访问鉴别(Access Authentication)
HTTP提供了一个简单的质询回应(challenge-response)鉴别机制,可用于服务器通过客户端提供的授权信息来对其进行身份鉴别。授权方案用可扩展的、大小写敏感的符号来标识,后跟获取证明所需要的以逗号分隔的‘属性-值’对。
auth-scheme = token
auth-param = token "=" quoted-string
原始服务器用401(未授权)回应消息来质询用户代理的授权。该回应必须包括WWW-授权标题域,而该WWW-授权标题域包括一个以上用于请求资源认证的参数(challenge)。
challenge = auth-scheme 1*SP realm *( "," auth-param )
realm = "realm" "=" realm-value
realm-value = quoted-string
凡涉及到参数(challenge)处理的授权方案都有realm属性(大小写敏感)。与标准URL(相对于被访问服务器root)联合使用的realm值(也是大小写敏感)用来定义保护区域。Realm使得服务器上的被保护资源被放在特殊的保护分区内,这些区域都有各自的授权方案和(或)授权数据库。Relm值是个字符串,通常由原始服务器来分配,对于授权方案来说,可能存在些附加的语法处理问题。
通常,用户代理在收到401(未授权)回应时,可能(也可能不会)希望服务器对其授权。如果希望授权,用户代理将在请求中加入授权请求标题(Authorization request-header)域。授权域值由信任证书组成,其中有对用户代理所请求资源领域的授权信息。
credentials = basic-credentials
| ( auth-scheme #auth-param )
可由用户代理通过信任方式来访问的区域由保护区域决定。如果早先的请求已经通过认证,在由授权方案,参数和(或)用户选择等所指定的时间间隔内,其它的请求可通过相同的信任来访问该保护区域。
Berners-Lee, et al Informational [Page 47]
除非由授权另行指定,否则单个保护区域的范围不能扩展到服务器之外。
如果服务器不希望通过请求来接受信任,它应当返回403(禁止)回应。
HTTP协议的访问授权不限于这种简单的质询回应(challenge-response)机制,还可以使用其它的方法,比如传输级加密或消息封装及通过附加标题域来指定授权信息等等。但是,这些方法不在本文档的讨论范围。
代理必须完全透明地处理用户授权,也就是说,它们必须在不做任何改动的前提下将WWW-授权及授权标题向前推送,也不可以对包含授权的回应进行缓存。HTTP/1.0不为客户端提供通过代理方式授权的方法。
11.1 基本授权方案(Basic Authentication Scheme)
用户代理必须对于每个领域(realm)通过用户标识(user-ID)及口令来对自身进行授权,这是基本授权方案的工作模式。Realm值应当被看作不透明的字符串,该值将用于同服务器端其它的realm值相比较。只有用户标识及口令通过受保护资源的认证,服务器才会给请求授权。授权参数没有可选项。
在接收到对受保护区域的未经认证的资源请求时,服务器应当回应一个质询(challenge),如下:
WWW-Authenticate: Basic realm="WallyWorld"
“WallyWorld”是由服务器分配的字符串,用于对请求URI所指定的受保护资源进行标识。
为了接收授权,客户端需要在基于64位(base64 [5])的证书中发送用户标识及口令,中间用冒号’:’分隔。
basic-credentials = "Basic" SP basic-cookie
basic-cookie = <base64 [5] encoding of userid-password,
except not limited to 76 char/line>
Berners-Lee, et al Informational [Page 48]
userid-password = [ token ] ":" *TEXT
如果用户代理希望发送用户标识”Aladdin”和口令“open sesame”,应当遵循下面的标题域形式:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Basic授权方案是对HTTP服务器资源的非授权访问进行过滤的非安全方法。它基于假定客户端与服务器端的连接是安全的,为什么说是假定呢,因为在实际的开放性网络中,使用basic授权方案往往存在许多不安全的地方。尽管如此,客户端仍然需要实现此方案,以与采用此种方案的服务器进行通讯。
12. 安全考虑(Security Considerations)
本节的描述对下面各角色有关:信息应用开发者、信息提供者、HTTP/1.0中受安全性限制的用户。本节仅是讨论安全问题,并对减少隐患提出了建议,但是并不提供对问题的最终解决办法。
12.1 客户授权(Authentication of Clients)
正如11.1节中所述,基本授权(Basic authentication)方案不是安全的用户授权方案,也不能用它来防止实体主体源码以文本方式在物理网络中传输。HTTP/1.0并不反对在目前日益突出的安全问题面前采用其它的授权方式及加密机制。
12.2 安全方法(Safe Methods)
客户端软件开发者应当注意,客户端软件代表用户在Internet上与其它方面交互,并应注意避免让用户知道其间发生的具体动作,这些动作可能会暴露对交互各方有重要意义的信息。
特别情况下,按协定来看,GET和HEAD方法应被视作是安全的,同重新获得数据应当没有什么不同。这就允许用户代理采用其它方法,如POST,在某种情况下,可能存在这样一种情况,即请求中包含不安全的行为。
Berners-Lee, et al Informational [Page 49]
通常,服务器端在执行过GET请求之后,其结果之类的副产品还残留在服务器上;实际上,一些动态资源需要这种特性来实现。这里的重要区别在于用户没有请求这些副产品,因而也不应当对这类请求进行解释。
12.3 服务器日志信息的弊端(Abuse of Server Log Information)
服务器为保存与用户请求相关的个人数据,如阅读方式或感兴趣的主题等提供了空间。这些存储信息显然是受某些国家法律保护的,所以对此类数据的处理应当小心。用HTTP协议提供数据的一方应当负责保证这些信息在未得各方许可之前不会散布出去。
12.4 敏感信息传输(Transfer of Sensitive Information)
与其它协议一样,HTTP协议不能调整传输数据的内容,也不存在未卜先知的方法,通过给定请求的上下文信息片段就能推测出信息的敏感程度。因而,应用程序应当尽可能像信息提供方一样,为该信息提供更多的控制。在此,有三个标题域值得一提:服务端(Server)、提交方(Referer)和来自(From)。
一些指定服务器软件的版本有启示作用,因为这些版本的软件存在一些安全漏洞,将使服务器更易受到攻击。提倡服务器软件在实现时,将Server标题域变成可以进行配置的选项。
提交方(Referer)标题域允许阅读方式(reading patterns)被暴露,并可导出反向链接。虽然该域很有用,但是如果包含在此域的用户信息如果没有被分开,则它的作用很可能被滥用。另外,即使此域中用户信息被清除,从该域的其它信息仍可推测出其私有文件的URI,这可能是该信息发布者所不想看到的。
来自(From)标题域可能包括一些与用户私人隐私及站点安全相关的信息,因而,在发送数据前,应当允许用户使用一些设定手段,如禁止(disable)、允许(enable)、及修改(modify),对此域信息进行配置。用户应当能够根据他们的选择或使用应用程序提供的缺省配置来设定此域的内容。
我们建议,但不做要求:为用户提供方便的界面来允许(enable)或禁止(disable)发送From域或Referer域的信息。
Berners-Lee, et al Informational [Page 50]