好久没写博客了,当初说好的要坚持写博客呢!都怪最近实在太忙了。。。
最近的工作中,需要根据实际场景处理HTTP请求,项目虽然已经有了现成的HTTP库,但是不能满足我们的需求,趁此机会正好好好学习一下HTTP。此文是HTTP权威指南的学习笔记,后续会写一系列的volley库、OKHTTP库的使用以及简单地源码分析,以及如何支持使用自签名证书的Https连接。下面就先记录一下HTTP权威指南这本书的学习笔记吧。
Http是基于TCP的应用层网络协议,基本上所有因特网上客户端与服务器端的通信都是使用Http协议的,可以说Http协议是做应用层必备的技能点。
1.MIME(Multipurpose Internet Mail Extension)
因特网上有不同类型的数据类型,HTTP给每种要通过Web传输的对象都打上了名为MIME类型的数据格式标签。MIME类型是一种文本标记,表示一种主要的对象类型和一个特定的子类型,中间由一条斜杠来分隔。HTML文档由text/html标记,ASCII文本由text/plain标记,JPEG图片由image/jpeg标记,GIF图片由image/gif标记。这些标记都被记录在header的Content-type中。
2.统一资源标识符URI(Uniform Resource Identifier)
服务器资源的名称被称为统一资源标识符URI。URI就像因特网上的邮政地址一样,在世界范围内唯一标识并定位信息资源。URI的表现形式有URL、URN(统一资源名)。
3.统一资源定位符URL(Uniform Resource Location)
统一资源定位符URL是资源标识符常见的形式。URL描述了一台特定服务器上某资源的特定位置,它们可以明确说明如何从一个精确、固定的位置获取资源。
URL包含三个部分。第一部分是scheme,说明访问资源所使用的协议类型;第二部分是服务器的因特网地址;第三部分是指定具体的某个资源。
4.常见的HTTP方法
GET:用于请求服务器向客户端发送资源;
HEAD:类似于GET,但服务器在响应中只返回头部,不包含主体;
PUT:将来自客户端的数据存储到服务器中;
DELETE:用于请求服务器删除请求URL所指定的资源;
POST:将客户端数据发送到一个服务器程序当中;用来支持HTML表单,表单中的数据会被发送至服务器并处理;
TRACE:对可能经过代理服务器传送到服务器上的报文进行追踪;客户端发起一个请求时,这个请求可能会穿过防火墙、代理、网关等一些网络应用程序,每个中间环节都有可能修改原始HTTP请求,TRACE方法允许客户端在最终将请求发送给服务器时,看看它变成什么样子。行程最后一站的服务器会弹回一条TRACE相应,并在相应主体中携带它收到的原始报文。
OPTIONS:用于请求Web服务器告知其支持的各种功能。
其中GET和HEAD被认为是安全方法,意味着客户端使用GET和HEAD方法的HTTP请求不会产生什么动作。
5.状态码
每条HTTP响应报文返回时都会携带一个状态码,它在每条响应报文的起始行返回的。状态码是一个三位数字的代码,告知客户端是否请求成功。常见的有:(1)200,正确返回;(2)302,重定向,去其他地方获取资源;(3)404,未找到,无法找到这个资源。200-299之间的状态码表示成功,300-399表示资源已经被移走了,400-499之间的代码表示客户端的请求出错了,500-599代表服务器出错了。
6.一个简单地连接过程
(1)浏览器从URL中解析服务器的主机名
(2)浏览器通过DNS服务将主机名转换成IP地址
(3)浏览器将端口号(如果有的话)从URL解析出来
(4)浏览器建立与服务器的TCP连接
(5)浏览器向服务器发送HTTP请求报文
(6)服务器向浏览器回送一条HTTP响应报文
(7)关闭连接,浏览器显示文档
7.HTTP协议版本
(1)0.9 有设计缺陷,很快被取代。
(2)1.0.广泛使用
(3)1.1.增加了很多新特性,如keep-alive、虚拟主机支持、代理连接
(4)2.0.性能大幅提升。
8.Web的结构组件
(1)代理
位于客户端和服务器端之间的HTTP实体。代理位于客户端与服务器端之间,接收所有客户端的HTTP请求,并转发至服务器(有可能会修改),通常会将代理作为转发所有Web流量的可信任中间节点使用。
(2)缓存
HTTP仓库,使常用页面的副本可以保存在离客户端更近的地方。Web缓存是一种特殊的HTTP代理服务器,可以将经过代理传送的常用文档保存起来,下一个请求同一个文档的客户端就可以享受缓存的私有副本提供的服务了。
(3)网关
连接其他应用程序的特殊Web服务器,作为其他服务器的中间实体使用。通常用于将HTTP流量转换成其他协议。
(4)隧道
隧道是建立起来之后,就会在两条链接之间对原始数据进行盲转发的程序。HTTP隧道通常用来在一条或者多条HTTP连接上转发非HTTP数据。隧道一种常见的用途是通过HTTP承载加密的安全套接字层(SSL,Secure Socket Layer)流量,这样SSL流量就可以穿过只允许Web流量通过的防火墙了。
(5)Agent代理
Agent代理是代表用户发起HTTP请求的客户端程序。所有发布Web请求的应用程序都是HTTP Agent代理,除了Web浏览器意外还有其他类型。
9.报文
HTTP报文可被分为两类:请求报文(request message)和响应报文(response message)。请求报文会向服务器请求一个动作,响应报文会将请求的结果返回客户端。
10.首部
(1)通用首部
有些首部提供了与报文相关的基本信息,被称为通用首部。如Connection:允许客户端和服务器指定与请求/相应连接有关的选项;Date:报文的创建时间;MIME-Version:客户端的MIME版本;Transfer-Encoding:编码方式;
(2)请求首部
请求首部是只在HTTP请求中有意义的首部。如Client-IP:客户端机器的IP地址;From:客户端用户的Email地址;Host:服务器端的主机号和端口号;Referer:提供了包含当前请求URI的文档的URL;
Accept首部为客户端提供了一种将其喜欢和能力告知服务器的方式,包括想要什么、可以是用什么、以及什么最重要、不想要什么。如Accept:告诉服务器能够发送那些媒体类型;Accep:Charset:告诉服务器能够发送哪些字符集;Accept-Encoding:告诉服务器能够发送哪些编码方式;Accept-Language:告诉服务器能够发送哪些语言。
条件请求首部:有时客户端希望为请求加上某些限制,如,客户端已经有了一份文档副本,就希望服务器端只在服务器上的文档与客户端拥有的副本有所区别时才请求服务器传输文档。如If-Match:如果实体标记与文档当前的实体标记相匹配,就获取这份文档;If-Modified-Since:除非在某个指定的日期之后资源被修改过,否则就限制这个请求;If-None-Match:如果提供的实体标记与当前文档的实体标记不相符,就获取文档。
(3)相应首部
服务器端相应客户端请求的首部信息。如Content-Encoding:对HTTP响应主体执行的任意编码方式;Content-Language:HTTP响应主体语言;Content-Length:HTTP响应主体长度。
11.连接管理
TCP为HTTP提供了一条可靠的比特传输管道,从TCP连接一端填入的字节会从另一端以原有的顺序、正确地传送出来。HTTP发送一条报文时,会以流的形式将报文数据的内容通过一条打开的TCP按序传输。TCP会将数据进行分块,并将数据封装在IP分组,通过因特网传输。
源IP、源端口号、目的IP、目的端口号定义了一条连接,也就是Socket。
小的HTTP事务可能会在TCP建立上花费50%的时间。
每个TCP段都有一个序列号和数据完整性校验和。每个段的接受者在收到完好的段时,都会向发送者回送小的确认分组。如果发送者没有在指定的时间内收到确认信息,发送者就会认为数据被破坏或损毁,自动重发。
当某个TCP端点关闭TCP连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的IP地址和端口号,这类信息只会维持在一小段时间,以确保在这段时间内不会创建具有相同地址和端口号的新连接。
12.长连接
HTTP 1.1之后的版本允许HTTP设备在事务处理结束之后将TCP连接保持打开状态,以便为未来的HTTP请求重用现存的连接。在事务处理结束之后仍然保持打开状态的TCP连接称之为长连接。长连接会在不同事务间保持打开状态,直到客户端或者服务器端决定将其关闭为止。重用保持连接状态的长连接可以避免缓慢的建立连接阶段,还可以避免TCP慢启动的拥塞适应阶段,达到更快传输数据的目的。但是管理长连接时要特别小心,不然就会累积出大量的空闲连接,耗费本地和服务器端的资源。长连接有两种类型:HTTP1.0版本的”keep-alive”连接,HTTP1.1版本的“persistent”连接。
keep-alive:如果服务器端愿意在下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有Connection:Keep-Alive首部,客户端就认为服务器端不支持keep-alive,会在响应报文之后关闭连接。keep-alive首部只是请求将连接保持在活跃状态,发出keep-alive请求之后,客户端和服务器端不一定会同意进行keep-alive会话。它们可以在任意时刻关闭空闲的keep-alive连接,并可限制keep-alive连接所处理的事务数量。参数timeout是在Keep-Alive响应首部中发送的,它估计服务器还希望将连接保持活跃状态的时间。参数max估计了服务器还希望为多少个事务保持此连接的活跃状态。如Connection : Keep-Alive; Keep-Alive:max = 5, timeout = 120; 请求首部中必须包含Content-Length。
HTTP 1.1默认情况下是长连接是激活的,除非特别指明,HTTP 1.1假定所有连接都是持久的。要在事务处理结束之后关闭,必须要在首部中添加 Connection:close。
13.Web服务器工作内容
(1)接受客户端的连接
(2)接受请求报文
(3)处理请求
(4)对资源的映射和访问
(5)访问控制
(6)发送相应
(7)记录日志
14.代理
Web代理(Proxy)服务器是网络的中间实体,代理位于客户端与服务器之间,扮演中间人的角色,在各端点之间来回传送HTTP报文。HTTP代理服务器既是Web服务器又是Web客户端,代理服务器需要处理客户端的请求和连接,还要像服务器端发送客户端的请求。
代理服务器可以是某个客户端专用的,也可以是多个客户端公用的。单个客户端使用的叫做私有代理,否则就是公共代理,大多数的代理都是公共代理。
代理与网关的区别:代理连接的是两个或多个使用相同协议的应用程序,而网关连接的则是两个或多个使用不同协议的端点。网关扮演的是协议转换器的角色,既是客户端和服务器使用的是不同的协议,客户端也可以通过它完成与服务器端的事务处理。
为什么使用代理:(1)儿童过滤器(2)文档访问控制。可以用代理服务器在大量Web服务器和Web资源之间实现统一的访问控制策略,创建审核跟踪机制。(3)安全防火墙。(4)Web缓存。(5)反向代理。代理可以假扮Web服务器,接收发给Web服务器的真是请求,但与Web服务器不同的是,它们可以发起与其他服务器的通信。可以使用反向代理来提高访问慢速Web服务器上公共内容时的性能,通常可以将这些反向代理称之为服务器加速器。(6)内容路由器。(7)转码器。
15.Web缓存
Web缓存是可以自动保存常见文档副本的HTTP设备。当Web请求到达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中提取文档。优点如下:(1)缓存减少了冗余的数据传输(2)缓存缓解了网络瓶颈的问题(3)缓存降低了对原始服务器的要求(4)缓存降低了距离时延。
原始服务器的内容可能会发生改变,缓存要时不时对其进行检测,看看它们保存的副本是否仍是服务器上的最新副本,这些“新鲜度检测”被称为HTTP再验证。缓存对缓存的副本进行再验证时,会向原始服务器发送一个小的再验证请求,如果内容没有发生变化,服务器会以一个小的304 Not Modified进行相应。然后缓存会将副本提供给客户端,这被称为再验证命中。HTTP为我们提供了几个用来对已缓存的对象进行验证的工具,最常用的是If-Modified-Since首部。将这个首部添加到GET请求中,就可以告诉服务器,只有在缓存了对象的副本之后又对其进行了修改,才发送此对象。
缓存的处理步骤:(1)接收:缓存从网络中读取抵达的请求报文(2)接收:缓存对报文进行解析,提取URL和各种首部(3)查询:缓存查看是否有本地副本可用,如果没有,就获取一份副本,并保存在本地(4)新鲜度检测:缓存查看已缓存副本是否足够新鲜,如果不是,就询问服务器是否有任何更新(5)创建相应:缓存会用新的首部和已缓存的主体来构建一条响应报文(6)发现:通过网络将响应发送给客户端(7)创建日志
16.cookie机制
cookie是识别用户、实现持久会话的最好方式。cookie可以笼统的分为两类:会话cookie和持久cookie。会话cookie是一种临时cookie,记录了用户访问站点时的设置和偏好。用户推出浏览器时,会话cookie就被删除了。持久cookie的生存时间更长,存储在本地,计算机重启之后仍在存在。通常会用持久cookie维护某个用户会周期性访问的站点。会话cookie和持久cookie的区别就在于过期时间。
cookie的基本思想就是让浏览器积累一组服务器特有的信息,每次访问服务器时都将这些信息提供给它。
17.数字加密
密码:对文本进行编码,使偷窥者无法识别的算法。
密钥:改变密码行为的数字化参数。
对称密钥加密系统:加、解密使用相同密钥的加密算法,如DES、Triple-DES、RC2。
非对称密钥加密系统:加、解密使用不同密钥的加密算法。
数字签名:用来验证报文未被伪造或者篡改的校验和。除了加解密报文之外,还可以用加密系统对报文进行签名,以说明是谁编写的报文,同时证明报文未被篡改过。这种技术被称为数字签名。数字签名是附加在报文上的特殊加密校验码。
数字证书:由一个可信的组织验证和签发的识别信息。数字证书一般会包含以下信息:对象名称(人、服务器、组织)、过期时间、证书发布者、来自证书发布者的数字签名、对象的公开密钥。大多数证书都是一种叫做X.509 v3格式。X.509 v3提供了一种标准的方式,将证书信息规范至一些可解析的字段中。基于X.509的证书也有好几种,Web服务器证书、客户端电子邮件证书、软件代码签名证书、证书颁发机构证书。
明文:加密之前的原始报文;密文:加密之后的编码报文。
暴力破解:好的加密算法会迫使攻击者尝试每一个可能的密钥,才能破解代码。用暴力去尝试所有的密钥值的方式称为枚举攻击或暴力破解。可用密钥值的数量取决于密钥中的位数,以及可能的密钥中多少是有效的。就对称加密而言,所有的密钥值都是有效的。8位的密钥值只有256个可能值,40位的密钥值有2的40次方的可能值。对于对称加密,128位密钥被认为是非常强大的。
公开密钥加密技术:公开密钥加密技术使用了两个非对称密钥,一个用来对主机报文编码,另一个用来对主机报文解码。编码密钥是众所周知,但只有主机才知道私有的解密密钥,典型的非对称加密算法如RSA。RSA算法的原理基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对乘积进行因式分解极其困难,因此可以将乘积公开作为加密密钥。
18.HTTPS
HTTPS是在HTTP之下、TCP之上提供了一个传输级的安全密码层,可以使用SSL或者TSL。大部分困难的编码和解码工作都是在SSL库中完成的,因此客户端和服务器端在使用HTTPS时无需过多的修改协议逻辑处理部分。大多数情况下,只需要使用SSL的输入/输出代替TCP的调用,再增加其他几个调用来配置和管理安全信息就行了。
SSL使用证书来创建安全连接,有两种验证模式:(1)仅客户端验证服务器的证书,客户端不提供证书(2)客户端和服务器端都验证对方的证书。第二种安全性更高,但普通web网站均只采用第一种。浏览器中会内置最权威的根证书,浏览器可以使用根证书去验证某个服务器的证书是否有效。要提供一个有效的证书,服务器证书必须从VerSign这样的证书颁发机构签名,这样浏览器就可以通过认证,否则浏览器会给出证书无效的警告。
通过HTTPS建立起一个安全Web事务之后,现代的浏览器都会自动获取服务器的数字证书。如果服务器没有证书,安全连接就会失败。服务器证书包含很多字段,Web站点名称和主机名,Web站点的公开密钥,签名颁发机构的名称,来自签名颁发机构的签名。浏览器收到证书时会对签名颁发机构进行检查。如果这个机构是个很有权威的公共签名机构,浏览器可能已经知道其公开密钥(浏览器会预置很多签名颁发机构的证书)。
当客户端对某Web资源执行某事务时,它会去检查URL的方案。如果URL的方案是HTTP,客户端就会打开一条到服务器端口80的连接,并向其发送HTTP命令。如果URL的方案是HTTPS,客户端就会打开一条到服务器端口443的连接,然后与服务器“握手”,以二进制格式与服务器交换一些SSL安全参数,附上一些HTTPS命令。建立了TCP连接之后,客户端和服务器端会初始化SSL层,对加密参数尽心沟通,并交换密钥,将报文发送给TCP之前要先对其进行加密。在发送已加密的HTTP报文之前,客户端和服务器端要进行一次SSL握手,这个握手的过程主要完成以下的工作:交换协议版本号、选择一个两端都了解的密码、对两端的身份进行认证、生成临时的会话密钥用来加密通道。
OpenSSL是SSL和TLS的常见的开源实现。
19.重定向和负载均衡
现代网络中重定向是普遍的,出于:可靠地执行HTTP事务、最小化时延、节约网络带宽等原因,Web内容通常分布在很多地方。如果一个位置出了问题,还有其他的可用,如果客户端能访问较近的资源,就可以更快的收到所请求的内容,将服务器分散还能减少网络拥塞。大多数重定向部署都包含了某些形式的负载均衡。也就是说,它们可以将输入报文的负载均衡到一组服务器上去。反之,因为输入报文一定会在分担负荷的服务器之间进行某种分布,所以任意形式的负载均衡都包含着重定向。Web服务器会根据每个IP来处理请求,将请求分摊到复制的服务器中,也就意味着应该把特定URL的每条请求都发送到最佳的Web服务器上去。
HTTP重定向:Web服务器可以将短的重定向报文发回给客户端,告诉他们去其他地方试试。有些Web站点会将HTTP重定向作为一种简单地负载均衡形式来使用。处理重定向的服务器找到可用的负载最小的服务器,并将浏览器重定向到那台服务器上。对广泛分布的Web站点来说,确定最佳的服务器不仅要考虑服务器的负载,还要考虑浏览器和服务器之间的因特网距离。HTTP重定向有以下几个缺点:需要原始服务器进行大量处理来判断要重定向到哪台服务器上,增加了用户时延,如果重定向服务器出了故障就会瘫痪。
DNS重定向:DNS允许将几个IP地址关联到一个域中,可以配置DNS解析程序,对其进行编程,以返回可变的IP地址。