前言
TCP三次握手的过程:
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束.
HTTP协议
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有
接收到请求之前不会发送响应。
HTTP是一种不保存状态,即无状态协议.HTTP协议自身不对请求和响应之间通信状态进行保存.也就是说在HTTP这个级别,协议对于发送的请求或者响应不做持久化处理.
请求报文
请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成的
响应报文
响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成
HTTP/1.0和HTTP/1.1支持的方法
方法 | 说明 | 支持的HTTP协议版本 |
---|---|---|
GET | 获取资源 | 1.0、1.1 |
POST | 传输实体主体 | 1.0、1.1 |
PUT | 传输文件 | 1.0、1.1 |
HEAD | 获得报文首部 | 1.0、1.1 |
DELETE | 删除文件 | 1.0、1.1 |
OPTIONS | 询问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立和资源之间的联系 | 1.0 |
UNLINE | 断开连接关系 | 1.0 |
GET方法
获取资源,GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是像CGI(CommonGatewayInterface,通用网关接口)那样的程序,则返回经过执行后的输出结果。
POST方法
POST方法用来传输实体的主体,POST方法和GET方法功能很相似,但是传输实体的主体用POST方法而不用GET方法。
PUT方法
PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的Web网站不使用该方法。若配合Web应用程序的验证机制,或架构设计采用
REST(REpresentationalStateTransfer,表征状态转移)标准的同类Web网站,就可能会开放使用PUT方法。
HEAD方法
HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。
DELETE方法
DELETE方法用来删除文件,是与PUT相反的方法。DELETE方法按请求URI删除指定的资源。
但是,HTTP/1.1的DELETE方法本身和PUT方法一样不带验证机制,所以一般的Web网站也不使用DELETE方法。当配合Web应用程序的验证机制,或遵守REST标准时还是有可能会开放使用的。
OPTIONS方法
OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
CONNECT方法
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(SecureSocketsLayer,安全套接层)和TLS(TransportLayerSecurity,传输层安全)协议把通信内容
加密后经网络隧道传输。
HTTP中的持久化连接
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。
持久化连接
为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。
管道化
之前发送请求后需要等待并收到响应,才能发送下一个请求,管道化技术出现后,不用等待响应就可以直接发送下一个请求.
HTTP报文
HTTP报文大致可以分为报文首部和报文主体两块,两者由最初出现的空行来划分,通常,并不一定有报文主体.
请求报文和响应报文结构
请求报文和响应报文对的首部内容由以下数据组成:
-
请求行:包含用于请求的方法,请求URL和HTTP版本.
-
状态行:包含表明响应结果的状态码,原因语句和HTTP版本.
-
首部字段:包含表示请求和响应的各种条件和属性的各类首部.
- 通用首部
- 请求首部
- 响应首部
- 实体首部
-
其它:可能包含HTTP的RFC里未定义的首部.
编码
HTTP报文的主体用于传输请求或响应的实体主体,通常,报文主体等于实体主体,只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异.
常用的内容编码有以下几种:
- gzip(GNU zip)
- compress(UNIX系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
HTTP状态码
状态码类别
类别 | 原因语句 | |
---|---|---|
1XX | Informational(信息性状态码) | 收到的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
通信数据转发程序
-
代理:代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
-
网关:网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。
-
隧道:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
代理
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
代理可以分为缓存代理和透明代理:
- 缓存代理:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
- 透明代理: 转发请求或响应时, 不对报文做任何加工的代理类型被称为透明代理 。 反之, 对报文内容进行加工的代理被称为非透明代理。
网关
网关的工作机制和代理十分相似。 而网关能使通信线路上的服务器提供非 HTTP 协议服务。利用网关能提高通信的安全性, 因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。 比如, 网关可以连接数据库, 使用SQL语句查询数据。 另外, 在 Web 购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。
隧道
HTTP首部
HTTP协议的请求和响应报文中必定含HTTP首部,只是我们平时在使用Web的过程中感受不到它.
HTTP报文首部图片:
HTTP协议的的请求和响应报文中必定含HTTP首部,首部内容为客户端和服务器分别处理请求和响应提供所需要的的信息.对于客户端来说,这些信息中的大部分内容都无需亲自查看.
HTTP请求报文
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
HTTP响应报文
在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段组成。
HTTP首部字段分为四种类型:
- 通用首部字段:请求报文和响应报文两方都会使用的首部。
- 请求首部字段:从客户端向服务器端发送请求报文时使用的首部。
- 响应首部字段:从服务器端向客户端返回响应报文时使用的首部。
- 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。
通用首部字段:
请求首部字段:
响应首部字段:
实体首部字段:
首部字段
通用首部字段:
- Cache-Control:控制缓存的行为
- 缓存请求指令
- no-cache:强制向服务器再次验证
- no-store:不缓存请求和响应的任何内容
- max-age:响应中的最大Age值
- max-stale:接受已过期的响应
- min-fresh:期望在指定时间内的响应仍有效
- no-transform:代理不可更改媒体类型
- only-if-cached:从缓存获取资源
- cache-extension:新指令标记
- 缓存响应指令
- public:可向任意方提供响应的缓存.
- private:可向特定用户返回响应
- no-cache:缓存前必须确定其有效性
- no-store:不缓存请求和响应的任何内容
- no-transform:代理不可更改媒体类型
- must-revalidate:可缓存但必须再向服务器进行确认
- proxy-revalidate:要求中间缓存服务器对缓存的响应有效性在进行确认
- s-maxage:公共缓存服务器响应的最大Age值
- 缓存请求指令
- Connection
- 控制不在转发给代理的首部字段
- 管理持久连接
- Date
- Pragma
- 该首部字段属于通用首部字段,但只用在客户端发送的请求中.客户端会要求所有的中间服务器不返回缓存的资源
- Trailer
- 首部字段Trailer会事先说明报文主体后记录哪些首部字段.
- Transfer-Encoding
- 首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
请求首部字段:
- Accept
- Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。
- Accept-Charset
- Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。
- Accept-Encoding
- Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
- Accept-Language
- 首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。
- Authorization
- 首部字段Authorization是用来告知服务器,用户代理的认证信息(证书值)。
- Form
- 首部字段From用来告知服务器使用用户代理的用户的电子邮件地址。
- Host
- 首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。
响应首部字段:
- Accept-Ranges
- 首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请
求,以指定获取服务器端某个部分的资源。
- 首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请
- Age
- 首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
- ETag
- 首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag
值。
- 首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag
- Location
- Proxy-Authenticate
- 首部字段Proxy-Authenticate会把由代理服务器所要求的认证信息发送给客户端。
- Retry-After
- Server
- 首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。
- Vary
- 首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。
- WWW-Authenticate
实体首部字段:
- Allow
- Content-Encoding
- Content-Language
- Content-Length
- Content-Location
- Content-MD5
- Content-Range
- Content-Type
- Expires
HTTPS
HTTP的不足:
- 通信使用明文,内容可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
HTTPS = HTTP + 加密 + 认证 + 完整性保护
为了统一解决上述这些问题,需要在HTTP上再加入加密处理和认证等机制.我们把添加了加密及认证机制的HTTP称为HTTPS(HTTP Secure)
HTTPS是身披SSL外壳的HTTP
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL(SecureSocketLayer)和TLS(TransportLayerSecurity)协议代替而已。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
SSL是独立于HTTP的协议,所以不光是HTTP协议,其他运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。可以说SSL是当今世界上应用最为广泛的网络安全技术。
相互交换密钥的公开密钥加密
SSL采用一种叫做公开密钥加密的加密处理方式.加密和解密都需要用到密钥.没有密钥就无法对密钥加密,反过来说,任何人只要持有密钥就能解密.
- 共享密钥加密:
加密和解密同用一个密钥的方式称为共享密钥加密,也称为对称密钥加密. 以共享密钥方式加密时必须将密钥也发给对方。
- 使用两把密钥的公开密钥加密:
公开密钥加密方式很好的解决了共享密钥加密的困难.公开密钥加密使用一对非对称的密钥.一把叫做私有密钥,另一把叫做公开密钥,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人的都可以获得.
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密.利用这种方式,不需要发送用来解密的私有密钥,也不用担心密钥被攻击者窃听而盗走.
- HTTPS采用混合加密机制
HTTPS安全通信机制
- 客户端通过发送ClientHello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件(CipherSuite)列表(所使用的加密算法及密钥长度等)。
- 服务器可进行SSL通信时,会以ServerHello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 之后服务器发送Certificate报文。报文中包含公开密钥证书。
- 最后服务器发送ServerHelloDone报文通知客户端,最初阶段的SSL握手协商部分结束。
- SSL第一次握手结束之后,客户端以ClientKeyExchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-mastersecret的随机密码串。该报文已用步骤3中的公开密钥进行加密。
- 接着客户端继续发送ChangeCipherSpec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-mastersecret密钥加密。
- 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器同样发送ChangeCipherSpec报文。
- 服务器同样发送Finished报文。
- 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
- 应用层协议通信,即发送HTTP响应。
- 最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCPFIN报文来关闭与TCP的通信。
HTTPS认证
HTTP/1.1使用的认证方式如下所示:
- BASIC认证(基本认证)
- DIGEST(摘要认证)
- SSL客户端认证
- FormBase(基本表单认证)
BASIC认证
BASIC认证步骤:
- 步骤一:当请求的资源需要BASIC认证时,服务器会随状态码401AuthorizationRequired,返回带WWW-Authenticate首部字段的响应。该字段内包含认证的方式(BASIC)及Request-URI安全域字符串(realm)。
- 步骤二:接收到状态码401的客户端为了通过BASIC认证,需要将用户ID及密码发送给服务器。发送的字符串内容是由用户ID和密码构成,两者中间以冒号(:)连接后,再经过Base64编码处理。
- 步骤三:接收到包含首部字段Authorization请求的服务器,会对认证信息的正确性进行验证。如验证通过,则返回一条包含Request-URI资源的响应。
全双工通信的WebScoket
一旦Web服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。
由于是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确立WebSocket通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
WebScoket优点:
- 推送功能
支持由服务器向客户端推送数据的推送功能。这样,服务器可直接发送数据,而不必等待客户端的请求。 - 减少通信量
只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了。