读RFC 2616(超文本传输协议——HTTP/1.1)笔记

Jun 19th, 2008

转载本站文章请注明,转载自:扶凯[http://www.php-oa.com]

本文链接: http://www.php-oa.com/2008/06/19/durfc2616chaowenbenchuanshuxieyieeeehttp11biji.html

 

  在 HTTP/1.0 中,大多实现为每个请求/响应交换使用新的连接。在 HTTP/1.1 中,一个连接可用于一次或多次请求/响应交换,尽管连接可能由于各种原因被关闭.这是他们之间最大的分别.
 

有关URI的长度.服务器应当小心决定 URI 长度超过 255 字节,因为一些老的客户端或代理实现可能不能正确支持这种长度。

 HTTP 日期/时间戳【必须】以格林尼制标准时间(GMT)表示.所以我们中国的时区有8个小时的分别.

  为了与 HTTP/1.0 应用程序兼容,包含 message-body 的 HTTP/1.1 请求【必须】包括有效的 Content-Length 头部域,除非已知服务器与 HTTP/1.1 兼容。如果请求包含 message-body但没有给出 Content-Length,则服务器【应该】在不能判断消息长度时用 400(Bad Request)响应,或在希望坚持接收有效 Content-Length 时用 411(Length Required)响应

在http中的Request的结构.

Request = Request-Line ; 5.1 节
         *(( general-header ; 4.5 节
         | request-header ; 5.3 节
         | entity-header ) CRLF) ; 7.1 节

总结:Request(  在消息的首先中,从客户端到服务器的请求消息包括应用到资源的方法、资源的标识符和使用的协议版本。相当我们对网站的http的请求)

Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Method = "OPTIONS" ; 9.2 节
          | "GET" ; 9.3 节
          | "HEAD" ; 9.4 节
          | "POST" ; 9.5 节
          | "PUT" ; 9.6 节
          | "DELETE" ; 9.7 节
          | "TRACE" ; 9.8 节
          | "CONNECT" ; 9.9 节
          | extension-method
extension-method = token
Request-URI = "*" | absoluteURI | abs_path | authority
request-header = Accept ; 14.1 节
                 | Accept-Charset ; 14.2 节
                 | Accept-Encoding ; 14.3 节
                 | Accept-Language ; 14.4 节
                 | Authorization ; 14.8 节
                 | Expect ; 14.20 节
                 | From ; 14.22 节
                 | Host ; 14.23 节
                 | If-Match ; 14.24 节
                 | If-Modified-Since ; 14.25 节
                 | If-None-Match ; 14.26 节
                 | If-Range ; 14.27 节
                 | If-Unmodified-Since ; 14.28 节
                 | Max-Forwards ; 14.31 节
                 | Proxy-Authorization ; 14.34 节
                 | Range ; 14.35 节
                 | Referer ; 14.36 节
                 | TE ; 14.39 节
                 | User-Agent ; 14.43 节

  Response = Status-Line ; 6.1 节
             *(( general-header ; 4.5 节
             | response-header ; 6.2 节
             | entity-header ) CRLF) ; 7.1 节
              CRLF
             [ message-body ] ; 7.2 节

总结:Response(在接收并解析请求消息后,服务器以 HTTP 响应消息响应。相当服务器对客户的http的回应)

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

Status-Code 的首位数字定义响应的类别。最后两个数字没有任何分类。首位数字有 5个值:
  ·1xx:   信息性——收到请求,继续处理
  ·2xx:   成功性——成功收到、理解并接受行动
  ·3xx:   重定向——必须采取进一步行动来完成请求
  ·4xx:   客户端错误——请求包含错误语法或不能完成
  ·5xx:   服务器错误——服务器没有成功完成显然有效的请求
(这个是我们常常讲的http的状态码)Status-Code = "100" ; 10.1.1 节: Continue
              | "101" ; 服务器理解并愿意答应客户端的请求: Switching Protocols
              | "200" ; 请求已经成功: OK  
              | "201" ; 请求全部成功,且创建了新资源: Created
              | "202" ; 请求已经接受处理,但是处理还没有完成: Accepted
              | "203" ; 10.2.4 节: Non-Authoritative Information
              | "204" ; 10.2.5 节: No Content
              | "205" ; 10.2.6 节: Reset Content
              | "206" ; 10.2.7 节: Partial Content
              | "300" ; 10.3.1 节: Multiple Choices
              | "301" ; 所请求的资源已经指定到一个新的永久 URI: Moved Permanently
              | "302" ; 所请求的资源临时存在于不同的 URI: Found
              | "303" ; 10.3.4 节: See Other
              | "304" ; 但文档没有变化: Not Modified
              | "305" ; 10.3.6 节: Use Proxy
              | "307" ; 10.3.8 节: Temporary Redirect
              | "400" ; 服务器不能理解请求,由于畸形的语法: Bad Request
              | "401" ; 10.4.2 节: Unauthorized
              | "402" ; 10.4.3 节: Payment Required
              | "403" ; 10.4.4 节: Forbidden
              | "404" ; 服务器不能发现匹配 Request-URI 的任何东西: Not Found
              | "405" ; 10.4.6 节: Method Not Allowed
              | "406" ; 10.4.7 节: Not Acceptable
              | "407" ; 10.4.8 节: Proxy Authentication Required
              | "408" ; 10.4.9 节: Request Time-out
              | "409" ; 10.4.10 节: Conflict
              | "410" ; 10.4.11 节: Gone
              | "411" ; 10.4.12 节: Length Required
              | "412" ; 10.4.13 节: Precondition Failed
              | "413" ; 10.4.14 节: Request Entity Too Large
              | "414" ; 10.4.15 节: Request-URI Too Large
              | "415" ; 10.4.16 节: Unsupported Media Type
              | "416" ; 10.4.17 节: Requested range not satisfiable
              | "417" ; 10.4.18 节: Expectation Failed
              | "500" ; 10.5.1 节: Internal Server Error
              | "501" ; 10.5.2 节: Not Implemented
              | "502" ; 当作为网关或代理时,服务器从它靠近的上游服务器收到试图完成请求的无效响应: Bad Gateway
              | "503" ; 服务器当前不能处理请求,因为临时性的负载过重或服务器维护中。: Service Unavailable
              | "504" ; 10.5.5 节: Gateway Time-out
              | "505" ; 10.5.6 节: HTTP Version not supported
              | extension-code
extension-code = 3DIGIT
Reason-Phrase = *<TEXT,除 CR, LF 外>

response-header = Accept-Ranges ; 14.5 节
                  | Age ; 14.6 节
                  | ETag ; 14.19 节
                  | Location ; 14.30 节
          | Proxy-Authenticate ; 14.33 节
          | Retry-After ; 14.37 节
          | Server ; 14.38 节
          | Vary ; 14.44 节
          | WWW-Authenticate ; 14.47 节
entity-header = Allow ; 14.7 节
                | Content-Encoding ; 14.11 节
                | Content-Language ; 14.12 节
                | Content-Length ; 14.13 节
                | Content-Location ; 14.14 节
                | Content-MD5 ; 14.15 节
                | Content-Range ; 14.16 节
                | Content-Type ; 14.17 节
                | Expires ; 14.21 节
                | Last-Modified ; 14.29 节
                | extension-header
extension-header = message-header

HTTP/1.1 与较早版本的 HTTP 的明显区别是永久连接是任何 HTTP 连接的缺省行为。  该信号使用 Connection 头部域(14.10 节)来发生。一旦收到关闭信号,客户端<禁止>再发送任何更多的请求在该连接上。    HTTP/1.1 服务器<可以>假设 HTTP/1.1 客户端打算维护永久连接,除非所发送请求中的
Connection 头部中包括连接记号“close”。如果服务器选择在发送响应后立即关闭连接,它<应该>发送包括关闭连接记号的 Connection 头部。

总结:有关链接数.所以可以讲,在一个网页中,在http头中的Connection中有多少个close的头,就相当有多少个http的连接.

  服务器既可使用 Expires 头部,也可使用 Cache-Control 头部的 max-age(最大年龄值)指令来指定明确的截止时间。截止时间不能使用强制用户代理刷新它的显示或重新加载资源;它的语义只应用到缓存机制.
max-age 指令优先于 Expires,所以如果响应中存在 max-age,则计算是简单的:
更新周期=最大年龄值
否则,如果 Expires 存在于响应中,则计算方法是:
更新周期=截止值-日期值

总结:说明有Expires头和Cache-Control头后.缓存服务器是会根据这个来断定是否更新.这二个值优先级最高.

    既然原始服务器并非始终提供明确的截止时间,HTTP 缓存服务器一般指它启发式截止时间,用使用其它头部值(如同 Last-Modified 时间)的算法来估计好象有理的截止时间。
总结:squid之类,如果没有指明前二个的截止时间,那它就会使用发式截止时间,如参考 Last-Modified.
HTTP/1.1 需要原始服务器尽可能在每个响应中发送 Date 头部,它给响应生成的时间.
  HTTP/1.1 使用 Age 响应头部来传输从缓存服务器获取时的响应消息的估计年龄。Age域值是缓存服务器估计从响应产生或被原始服务器重新证实以来的总时间
, Age 值是响应已经在从原始服务器到每个缓存服务器中停留的总时间,加上在网络路径上传输的总时间。

年龄值”表示 Age 头部的值,以适合算法运算的形式。
  响应的年龄可以用两种完全独立的方式来计算:
  1、“现在”减去“日期值” ,如果假设本地时钟与原始服务器的时钟很好地同步。如果结果是负数,则结果用 0 代替。
  2、“年龄值”,如果响应路径上的所有缓存服务器都实现 HTTP/1.1。
  上面给出我们有两种独立的方式计算所收到响应的年龄,   我们可以将它们组合为: 正确的接收年龄=取最大值(现在-日期值,年龄值) 且如果我们有几乎同步的时钟或全为 HTTP/1.1的路径,就可得到可靠(保守的)的结果。
总结当缓存服务器收到响应的年龄的计算算法:
/*
* 年龄值
*    是 Age 的值:缓存服务器收到的该响应的头部
* 日期值
*    是原始服务器 Date 头部的值
* 请求时间
*    是缓存服务器作出导致缓存服务器的响应的请求的(本地)时间
* 响应时间
*    缓存服务器收到响应的(本地)时间
* 现在
*    当前(本地)时间
*/
外观年龄=取最大值(0,响应时间-日期值)   ;
修正接收年龄=取最大值(外观年龄,年龄值)     ;
响应延迟=响应时间-请求时间;
修正发起年龄=修正接收年龄+响应延迟;
常驻时间=现在-响应时间;
当前年龄=修正发起年龄+常驻时间;
   响应中存在 Age 头部意味着该响应不是第一手的。然而,返过来就不成立,因为响应中缺少 Age 头部域并不意味着该响应是第一手的,除非请求路径上的所有缓存服务器都与HTTP/1.1 一致(例如,老版 HTTP 缓存服务器并不实现 Age 头部域)

总结:其实这个我很多不明白…下次在看看,有一点明白,如果中间有缓存服务器,就会有个age的头,age的值是缓存服务器算出来的,原始服务器是没有的.

public  指出该响应【可以】被任何缓存器缓存,即使它通常是不可缓存的(其它细节另见 Authorization、14.8或只在非共享缓存中可缓存的。)
private 指出响应消息中的所有部分是用于单个用户的且【禁止】被共享缓存器所缓存。这允许原始服务器使只用于一个用户的响应和对其他用户所请求的无效响应的指定部分过期。私有(非共享)缓存【可以】缓存该响应。

总结:这二个很有意思。基实理解为public可以在任何地方被缓存就好了,如中间的缓存服务器和客户端的IE.但private在中间的缓存服务器是不能缓存的,只有用户的IE可以.

                         

 

Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪 ViVi 365Key 网摘 天极网摘 和讯网摘 博拉网 POCO 网摘 饭否 QQ 书签 Digbuzz 我挖网 Mister Wong
  1. 飞鸽传书
    Dec 11th, 2008 at 13:53
    Reply | Quote | #1

    100 Continue 是否有研究过?

  2. admin
    Dec 11th, 2008 at 17:19
    Reply | Quote | #2

    100 Continue????不明白指的什么