HTTP协议-HTTP权威指南

1.HTTP基础

http的特点:
 支持B/S模式模式,无状态。
http消息:由2部分组成起始行(请求行或状态行)和MIME信息(头和内容)
http中介:有3种-服务器缓存代理、网关、隧道。代理根据URL的绝对格式来接收请求,重写全部或部分消息,通过URL的标识把格式化后的请求发送给服务器。网关是一个接收代理,作为一个其它服务器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。隧道作为不改变消息的2个连接之间的中继点,常用于通信需要通过一个中介(如防火墙)或者中介不能识别消息的内容的地方。

URL由9个部分组成:
<方案>://<用户名>:<密码>@<主机>:<端口>/<路径>;<参数>?<查询>#<片段>
 其中:// : @ / ; ? # 是各字段的分隔符,路劲后面的部分将存放在HTTP报文的实体部分被发送
方案:使用的协议,http,https,ftp
参数:某些方案可以用此来指定参数
  ftp://prep.ai.mit.edu/pub/gnu.giz;type=d 指定以2进制传输
  type为参数名,d为值
查询:某些方案用此传递查询条件以激活应用程序。
   http://www.joes.com/check.cgi?item=12731&color=red 通过查询字段给出查询条件
片段:一小片资源的名字。浏览器不会把该字段传送给服务器,服务器的资源都是一页一页访问的,如果用户想获取一页中的部分资源,那么浏览器会请求整个资源,但只显示指定的frage部分。
   http://www.joes.com/tools.html#drills 只请求/tools.html页面下的drills部分资源
报文向下游流动定理:不管是请求报文还是响应报文都向下游流动

2.HTTP报文-请求与响应

头部的整个部分的接收标志: 空行+CRLF
http方法:常用方法有以下7种
 *GET 从服务器请求获取一份文档 
 *PUT 将请求的主体部分存储在服务器上
 *HEAD 只从服务器获取文档的首部
 *POST 向服务器发送需要处理的数据
 *TRACE 对可能经过代理服务器传送到服务器上去的报文进行追踪。中介收到trace请求会将自己的主机地址添加到报文的via头部。目的主机在*响应的实体中发回接收的报文,这样客户端就可以判断请求是否被中介修改过。
 *OPTIONS 询问服务器是否支持某些方法或资源
 *DELETE 从服务器上删除一份文档
http头部分类:
 *通用头部 date connection MIME-Version Trailer via   pragma  update  transfer-encoding ...
 *请求头部 client-ip from host referer UA-color    UA-CPU UA-Disp UA-OS UA-Pixels UA-Agent accept  accept-*charset accept-encoding accept-language TE    if-match if-modified-since if-none-match if-range    if-*unmodified-since range authorization cookie    max-forward proxy-authorization...
 *响应头部 server age public retry-after title warning ..
 *实体头部 content-Type content-encoding content-length content-language content-location allow location ...
 *扩展头部 
实体可以承载的信息:图片 视频 html文档 电子邮件等
信息状态码:
 *100~199:信息状态码
 *200~299:成功状态码
 *300~399:重定向状态码
 *400~499:客户端错误状态码
 *500~599:服务器端错误状态码
3.HTTP中的TCP连接管理
一条tcp连接是通过4个值唯一识别的<src_ip,src_port,des_ip,des_port>,2条不同的连接不能拥有完全相同的4个值,源端的主动连接在同一时刻不可能有多个连接在同一端口src_port上。
HTTP的客户端与服务器的常规事务交互过程:
 *客户端从URL中解析出主机名和端口号
 *客户端通过DNS查询主机名的IP
 *客户端发起到主机IP+端口号的连接(3次握手)
 *客户端发起请求
 *服务器响应请求,客户端读取请求
 *服务器关闭读端口,客户端关闭读端口(连接关闭)
HTTP的事务时延(从交互过程可以看出)
 *如果最近没有对服务器主机进行访问,DNS解析服务器IP可能需要10+S的时间
 *TCP连接(3次握手)时延至多2S,但同时有多个连接到达服务器,那么这个时延会累加起来(串行处理)
 *服务器处理请求可能需要花费一定的时间
 *请求发送和响应回送都需要一定的时间
常见的TCP时延
 *TCP连接的3次握手(该过程对http程序员不可见):一个小的HTTP事务在连接建立上花的时间比太大
 *TCP进行拥塞控制采用的慢启动
 *TCP数据聚集的Nagle算法
 *用于捎带确认的TCP延迟确认算法
 *TIME_WAIT时延和客户端端口耗尽
TCP连接的3次握手时延
 *可以将客户端请求放入第3次客户端应答中去("捎带")
TCP延迟确认算法
 *每个TCP段都有一个序列号和校验和,接收者收到完好的段时都会响应一个小的确认分组,如果发送者没有在指定的窗口时间内收到确认信息,发送者任务分组已经被破坏,并重新发送数据。 由于确认分组很小,tcp允许在发往相同方向的数据分组中对其进行"捎带"。为了找到同向的数据分组,很多TCP栈都实现了"延迟确认"算法。该算法在一个特定的窗口时间100~200ms内将输出确认放在缓冲区内,以等待能够捎带它的数据分组,如果没有等到,确认信息就放在单独的分组中发送出去。
 *HTTP具有双峰特性的请求-应答机制降低了捎带信息的可能。所以在HTTP中延迟算法会引起很大的延时,根据操作系统的不同可以禁止延迟确认算法
TCP慢启动(流量控制)
 *TCP传输数据的性能还取决于TCP连接的使用期(age)。起初会限制数据发送的最大速度,如果数据成功传输(收到确认)一次,允许发送数据的最大速度会提高,这被称为TCP的慢启动。拥塞窗口慢慢的被打开。由于存在这种拥塞控制已经调谐的连接会比新的连接传输速度快。
Nagle算法(拥塞控制)
 *Nagle算法算法试图将大量发往同一个目的地的TCP数据绑定在一个包中,以提高网络效率,减少网络中包的数量。Nagle算法将数据缓存尽力全尺寸发送(以太网1500字节)
 *Nagle算法会引起HTTP性能问题:小的HTTP报文无法填满一个TCP分组,从而被缓存,导致较大延时。同时Nagle算法每发送一个包要等待确认信息才发送下一个包,否则重发上一个包,而延迟确认算法在目的端会缓存确认信息100~200ms,这将导致Nagle算法发送2个包之间的时延较大。
 *TCP_NODELAY参数可以禁止Nagle算法,提高发包速率,但要确保TCP写入大块的数据,这样不会产生一堆小的分组
端口耗尽(TIME_WAIT造成的端口耗尽)
 *TIME_WAIT端口耗尽是很严重的问题,影响了性能根基。原因:当某个TCP端点关闭TCP连接时,会在网卡内存中维持一个控制块,用来记录最近关闭连接的IP地址和端口号。TIME_WAIT维持时间为最大分段生存期(tcp报文在网络中的最长生存时间)的2倍,称为2MSL,通常为2min以上,以确保这段时间内不会创建具有相同IP和端口号的新的连接(否则网络上具有该IP和端口的数据可能到达新的TCP连接的数据缓存中)
 *tcp客户端每次连接到每次连接到服务器上去,都会获得一个新的源端口,以实现连接的唯一性。源端口是有限的,假如为60000个,但由于在2MSL内连接是不能重用的,每秒能连接的次数6000/120=500次/秒,这就可以确保不会遇到端口耗尽的问题
HTTP连接的处理
 *connection:close 要求对方在发送完下一条报文时,可以关闭连接
 *串行事务处理时延:如果串行的处理事务,每一事务建立自己的连接,那么TCP连接延时和慢启动延时会叠加起来。解决办法:并行连接,通过多条连接同时发送请求;持久连接,重用tcp连接;管道化连接,通过共享的tcp连接发起并发的http请求。
 *并行连接:将连接时间和事务处理重叠,可能会加快页面的加载速度。但也会收到网络带宽限制。
 *持久连接有2种类型:keep-alive和persistent: connection:keep-alive 客户端请求将连接保持在打开状态,如果服务器的返回中没有该头域,那么客户端认为服务器不支持keep-alive.persistent持久连接与keep-alive差不多
 *管道化连接:管道化连接就是持久连接上加了管道化请求,让服务器可以缓存客户端的消息。持久连接消除TCP连接延迟,管道化请求消除(重叠)传输延时。管道化请求要求响应按照请求的顺序回送。服务器出错时,客户端不知道发送的请求哪些没有执行。所以有些请求方法(非幂等请求:多次调用该方法会将产生的结果累积)不可以在管道化连接中发送,
HTTP关闭连接
 *服务器和客户端都可以在任意时刻关闭一条TCP连接
 *每条TCP响应都应该有精确的content-length头部,否则就只能依赖于服务器关闭连接来说明数据的真实末尾
 *tcp关闭和重置错误:关闭连接的读端口是很危险的,当B向A一个读端口已经关闭的连接中写数据时,A将会向B发送TCP"连接被对端重置"报文,收到这条报文后,B端的TCP栈将清除自己的输入缓存和输出缓存,当B端读缓存时,会得到"连接被对端重置错误"
 *安全关闭:不发送数据的一方应该首先关闭自己的输出端,当另一方也关闭自己的输出端时,连接被TCP栈完全关闭,这样不会发送重置的错误。
HTTP服务器的功能
 *建立连接-处理新连接,反DNS客户主机名识别,ident确定客户端用户
 *接收请求-解析请求行,读取报文头部,检测以CRLF结尾的标识头部结尾的空行,           读取content-length头部标识长度的请求主体。
    服务器有多种:单线程,多进程多线程,复用IO,复用IO的多线程服务器
 *处理请求
 *访问资源-访问docroot下的资源,访问权限控制
 *构造响应-
 *发送响应
 *记录事务处理过程
4.HTTP代理
 代理的运行:代理既是客户端又是服务器。客户端向代理发送请求报文,代理必须向服务器一样,正确的处理请求和连接,然后返回响应;同时,代理自身要向服务器发出请求,其行为像客户端一样,要发出请求并接收响应;如果代理要创建自己的http代理就要遵循http客户端和服务器制定的规则。
代理功能
 儿童过滤器、文档访问控制、安全防火墙、web缓存、反向代理、内容路由器(根据网络流量或内容类型将请求导向特定的服务器)、匿名者(主动删除客户端身份特性如IP、FROM、REFERER、URI的会话ID、cookie等首部)
代理与网关的区别
 代理连接的是2个或多个使用相同协议的应用程序,而网关连接的是2个或多个使用不同协议的的端点,扮演协议转换的功能。
代理服务器在网络中的部署
 *出口部署:部署在本网络连接internet的出口点,控制本网与外网的流量,提供防火墙保护。
 *访问(入口)代理:常常放在ISP访问点上,处理来自客户的聚合请求。
 *反向代理:通常部署在网络边缘,冒用服务器的名字和IP,这样所有的请求就会发送给代理
 *网络交换代理:部署在internet对等交换点,通过缓存来减轻internet的拥塞,并对流量进行监控
客户端的代理配置
 可以通过浏览器手动配置或代理自动配置(PAC)

5.HTTP缓存
缓存优点
 *减少了冗余的数据传输(通过向缓存请求数据)
 *缓减了网络带宽瓶颈的问题(客户请求通过几种不同网速的网络到达服务器,网络带宽将以最小带宽的网络决定,所以缓存能够在一定程度上提高网络带宽)
 *降低了对原始服务器的要求
 *降低了距离时延:对决绝瞬时拥塞(同一时间段服务器接收大量请求)和距离时延,效果较好
缓存的命中与未命中
 使用缓存中已有的副本为到达缓存的请求提供服务,称为命中;如果对应该请求没有副本而被转发给服务器,这被成为缓存的未命中。
再验证
 为了保证副本不过期,需要进行新鲜度检测,这称为http的再验证revalidation。 使用If-Modified-Since头部可以进行再验证,如果服务器未被修改将发送一个304 Not Modified响应,否则发送200 OK响应。如果该资源在服务器上已经被删除了,则服务器将发送404 Not Found响应。If-None-Match头部通过实体的唯一标签验证也是一种较好验证方法。再验证一般都使用If条件头部
缓存的工作过程
 *接收-从网络中读取抵达的请求报文
 *解析-缓存提取URL和各种首部
 *查询-查看是否有本地副本,如果没有,就获取一份副本并保持在本地
 *新鲜度检查-查看已缓存副本是否足够新鲜,如果不是,就询问服务器是否有任何更新(再验证)
 *创建响应-使用新的首部和已缓存的主体创建一条响应报文
 *发送响应-发送给客户端
 *日志-创建并记录一条日志
服务器控制缓存的能力
 *cache-control:no-store 将相应发给客户端,但是自身不缓存副本。
 *cache-control:no-cache 将相应发给客户端,自身缓存一份副本,但是没有再验证之前不能使用该副本。
 *cache-control:max-age 从服务器将文档传来时起,文档处于新鲜度的秒数。
 *cache-control: expires 新鲜度有效的绝对日期
 *cache-control: must-revalidate 强制新鲜度检测
客户端控制缓存的能力
 *cache-control: min-fresh=<s> 要求缓存至少在未来s秒内将文档保存新鲜
 *cache-control: no-cache 要求缓存对资源进行再验证
 *cache-control: no-store 要求缓存不能保留副本
 *cache-control: only-if-cached 缓存中有副本则发送,没有就算了


6.集成点:网关、隧道和中继
Web是一种强大的内容发布工具。Web浏览器是一种HTTP协议的应用程序,通过HTTP协议传输HTML标记文本,HTML标
记文本可以告知浏览器要显示的内容和如何显示这些内容。当然,除了网页之外,http还可以传输其他内容。
HTML网页可以使用frontpage软件来制作,后缀为.htm或.html。
HTML:超文本标记语言,旨在显示数据。 XML:可扩展标记语言,标签没有被预定义,是对HTML的补充,旨在传输数据而不是显示数据。

网关:实现HTTP协议与其他协议或应用通信,从而访问HTTP以外的资源。网关的种类很多,主要分为2大类:协议网关(HTTP/FTP,HTTPS/HTTP)和资源网关(应用程序服务器网关,数据库查询网关)
将HTTP流量导向网关时所使用的方式与将流量导向代理的方式相同,最常见的就是显示的配置浏览器,指明使用的网关地址,对流量进行透明拦截。
资源网关最常见的是应用程序服务器(网关)。工作过程为:客户端通过HTTP连接到应用程序服务器,但应用程序服务器将请求通过一个网关应用编程接口API发送给运行在服务器上的应用程序。(应用程序服务器和网关在同一台主机上)
第一个流行的应用程序网关API就是通用网关接口CGI(Common Gateway Interface),CGI是一个标准接口集,用以在URL与应用程序之间传递参数并启动应用程序。通过CGI可以调用任何语言编写的应用程序。
一条发向网关的http请求:
GET ftp://ftp.irs.gov/pub/00-index.txt HTTP/1.0
HOST: ftp.irs.gov
USER-AGENT:superbroser 4.2    #浏览器型号

隧道:作用允许用户通过HTTP连接发送非HTTP流量,这样就可以在HTTP上捎带其他协议数据,从而这类流量可以穿过只允许web流量通过的防火墙。
隧道需要一个隧道网关,通过隧道网关转发非HTTP流量数据,客户端与隧道网关之间的隧道建立过程使用CONNECT方法。具体过程如下:客户端发送一条CONNECT请求给隧道网关,
隧道网关建立到某服务器的TCP连接,并隧道网关返回客户端响应,这样就建立完成了客户端到隧道网关的HTTP隧道;客户端通过HTTP隧道发送的所有数据都被隧道网关直接转发给
TCP连接,某服务器发送的所有数据都会通过HTTP隧道转发给客户端。

网页机器人:和所以浏览器一样,网页机器人也属于HTTP客户端,但一般运行在高速计算机上。需要遵守HTTP规范。网页机器人需要考虑较多问题:根基、环路避免等

7.HTTP客户端身份识别的方法:
1).承载用户身份信息的HTTP首部:FROM;USER-AGENT;REFERER;AUTHORIZATION;CLIENT-IP;COOKIE等
2).客户端IP地址跟踪:使用socket连接可以获得客户端IP,但是IP不一定对应着某个用户
3).用户登录;用户认证成功后,浏览器每次访问时都会发送AUTHORIZATION首部用户认证信息
4).胖URL-嵌入识别信息:用户首次访问网络站点时(不带ID)服务器为其生成一个唯一的ID添加在URL后面,然后服务器会将这个被标识的客户端导向该网站所有的胖URL,服务器收到胖URL就回去查找该胖URL对应的用户信息
5).cookie:用于标识用户信息,以记录的形式被浏览器被保存在cookie数据库中。可以分为2类:会话cookie(用户退出浏览器时被删除)和持久cookie(作为文件保存在硬盘上)。服务器发送SET-COOKIE首部要求客户端产生一个cookie记录信息。
cookie存在隐私问题,设置浏览器可以禁止cookie的使用。
cookie产生过程:
客户端请求->
GET /index.html HTTP/1.0
HOST: www.joes-hardware.com
服务器响应:要求产生cookie,以便于使用客户端->
HTTP/1.0 200 OK
SET-COOKIE:ID="34294";DOMAIN="YAHO.COM"
CONTENT-TYPE:TEXT/HTML
CONTENT-LENGTH:1903
...
客户端重新发送请求,带有客户端cookie标志->
GET /index.html HTTP/1.0
HOST: www.joes-hardware.com
COOKIE:ID="34294"



本文转自 a_liujin 51CTO博客,原文链接:http://blog.51cto.com/a1liujin/1702080,如需转载请自行联系原作者
上一篇:Oracle dataGuard专题:利用rman创建standby


下一篇:解决虚拟机克隆CentOS系统后eth0消失,显示eth1的问题