《图解HTTP》学习笔记
第1章 了解Web及网络基础
1.3 网络基础TCP/IP
协议:种类不同的网络设备要互相通信,所有的一切活动都需要一种规则,把这种规则成为协议
TCP/IP 是互联网相关的各类协议族的总称
URL(统一资源标识符)与URI(统一资源标识符):
- URL是URI的子集
- URI就是在某一规则下能把一个资源独一无二地标识出来,
TCP/IP协议族里重要的一点就是分层:应用层、传输层、网络层、数据链路层
-
应用层:决定了向用户提供应用服务时通信的活动。HTTP、FTP、DNS
-
传输层:提供处于网络连接中的两台计算机之间的数据传输。TCP、UDP
TCP将上层的数据切割,标序号后传输
-
网络层:用来处理网络上流动的数据包。数据包是网络传输的最小数单位。
增加通信目的地的MAC地址后传递给下一层
-
链路层:处理连接网络的硬件部分。
1.4 密切相关IP、TCP、DNS
IP协议
IP(Internet Protocol)网络协议位于网络层。其实是一种协议的总称
作用是把各种数据包传递给对方。确保准确传送的两个条件就是IP地址和MAC地址
通信通常会经过多台计算机与网络设备的中转。在进行中转时,会利用下一站中转设备的MAC地址来搜索下一个中转目标。
ARP 是一种用以解析地址的协议。根据通信方的IP地址就能反查出对应的MAC地址
可靠TCP
TCP位于运输层,提供面向连接的,可靠的字节流服务
三次握手
-
第一次握手(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入
SYN_SEND
状态。 -
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入
SYN_RCVD
状态。 -
第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入
ESTABLISHED
状态,当服务器端接收到这个包时,也进入ESTABLISHED
状态,TCP 握手结束。
握手丢包
- 客户端第一个「SYN」包丢了
- 服务器不知道客户端发过包。
- 客户端会启动重传机制。根据《TCP/IP详解卷Ⅰ:协议》中的描述,此时会尝试三次,间隔时间分别是 5.8s、24s、48s,三次时间大约是 76s 左右
- 服务端收到「SYN」并回复的「SYN,ACK」包丢了
- 客户端会认为[SYN]丢了,启动步骤一的重传机制
- 服务端超时后也会触发重传。会依次等待 3s、6s、12s 后,重新发送「SYN,ACK」包。 Linux默认重试次数为5
- 客户端最后一次回复「SYN,ACK」的「ACK」包丢了。
- 此时客户端已进入ESTABLISHED 状态,认为连接已建立,会立即发送数据
- 服务端会走重传机制。但是已处于SYN-RCVD状态,但是可以正常接收数据并进入ESTABLISHED 状态
当客户端在 ESTABLISHED 状态下,开始发送数据包时,会携带上一个「ACK」的确认序号,所以哪怕客户端响应的「ACK」包丢了,服务端在收到这个数据包时,能够通过包内 ACK 的确认序号,正常进入 ESTABLISHED 状态。
四次挥手
socket 编程中,任何一方执行 close()
操作即可产生挥手操作。
-
第一次挥手(FIN=1,seq=x)
假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。
发送完毕后,客户端进入
FIN_WAIT_1
状态。 -
第二次挥手(ACK=1,ACKnum=x+1)
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。
发送完毕后,服务器端进入
CLOSE_WAIT
状态,客户端接收到这个确认包之后,进入FIN_WAIT_2
状态,等待服务器端关闭连接。 -
第三次挥手(FIN=1,seq=y)
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。
发送完毕后,服务器端进入
LAST_ACK
状态,等待来自客户端的最后一个ACK。 -
第四次挥手(ACK=1,ACKnum=y+1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入
TIME_WAIT
状态,等待可能出现的要求重传的 ACK 包。服务器端接收到这个确认包之后,关闭连接,进入
CLOSED
状态。客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入
CLOSED
状态。
域名解析DNS
DNS(Domain Name System) 服务是和 HTTP 协议一样位于应用层的 协议。 它提供域名到 IP 地址之间的解析服务
1.6 URL访问过程
第2章 简单的HTTP
客户端&服务端
请求访问文本或图像等资源的一端称为客户端, 而提供资源响应的一端称为服务器端。
不保存状态->Cookie
HTTP是一种无状态协议。
双方并不会对请求与相应做持久化处理,这样加快了速度。但是如何保持用户的登录状态?于是引入了Cookie技术。
Cookie
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息, 通知客户端保存 Cookie。
响应报文(带有Cookie信息)
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,
10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
客户端请求报文(带有Cookie)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
HTTP/1.0 与 HTTP/1.1方法
持久化连接
开始版本,每进行一次HTTP通信就要断开一次TCP连接。随着网页内容的增加这种方式出现了瓶颈。
从HTTP/1.1开始出现了持久化连接(默认开启)。HTTP Keep-alive,只要任意一段没有提示断开连接,则保持TCP连接状态。
管线化:随着持久化连接,管线化指发出一个请求,不必等待响应可直接发送下一个请求。
第3章 HTTP报文
HTTP报文:用于 HTTP 协议交互的信息
HTTP报文格式
HTTP报文一般分为报文首部和报文主体(可省略)
请求与相应实例如下
编码提升传输速率
内容编码
- 在实体内容上的编码格式。服务端原样压缩编码后发送,客户端解码。
- 常见格式:gzip、compress、deflate、identity
分块传输
- 把实体内容拆分成多块传输
第4章 HTTP状态码
HTT P 状态码负责表示客户端 HTTP 请求的返回结果、 标记服务器端 的处理是否正常、 通知出现的错误等工作
类别 | 原因短语 | |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
第5章 HTTP协作的Web服务器
通信转发
代理
代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务 器。 代理不改变请求 URI, 会直接发送给前方持有资源的目标服务 器。
好处:
- 利用缓存技术减少网络流量、访问控制、获取访问日志
根据是否缓存可以分为缓存代理(预先将资源副本保存在代理服务器)和透明代理(不对报文做任何加工)
网关
利用网关可以由 HTTP 请求转化为其他协议通信
网关和代理的工作机制很详细,而网关能使通信线路上的服务器提供非HTTP协议服务。
隧道
隧道可按要求建立起一条与其他服务器的通信线路, 届时使用 SSL等 加密手段进行通信。 隧道的目的是确保客户端能与服务器进行安全的 通信。
通话结束后隧道关闭,客户端无感知
缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。
第6章 HTTP首部
HTTP 首部字段是构成 HTTP 报文的要素之一。
首部格式
首部字段名: 字段值
Content-Type: text/html
Keep-alive: timeout=15, max=100
四种首部类型:通用首部字段、请求首部字段、响应首部字段、实体首部字段
通用首部字段
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、 连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
请求首部字段
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与 If-Match 相反) |
If-Range | 资源未更新时发送实体 Byte 的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中 URI 的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP 客户端程序的信息 |
响应首部字段
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
实体首部字段
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位: 字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
Cookie服务首部
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
- Set-Cookie
例如
Set-Cookie: name=value; expires=Tue, 05 Jul 2011 07:26:31
属性 | 说明 |
---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必需项) |
expires=DATE | Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象(若不指定则默 认为文档所在的文件目录) |
domain=域名 | 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名) |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie |
HttpOnly | 加以限制, 使 Cookie 不能被 JavaScript 脚本访问 |
- Cookie
Cookie: status=enable
第7章 HTTPS
HTTP缺点
HTTP及其他未加密的协议有如下缺点
- 通信使用明文不加密,内容被窃听
- 无法验证通信方的身份,因此有可能遇到伪装
- 无法正确报文完整性,可能遭到篡改
被窃听
互联网上的任何角落都存在通信内容被窃听的风险。比如可以用抓包工具Wireshark
为了防止窃听有两种方式
- 通信加密:用SSL建立安全的通信线路
- 内容加密:客户端对HTTP报文进行加密处理后发送请求。内容仍有被篡改的风险。
被伪装
HTTP的设计较为简单,对无论是谁发送过来的请求都会返回响应
解决:SSL不仅提供了加密处理,还提供了证书机制。
证书是由值得信赖的第三方机构颁发,用以证明服务器和客户端是实际存在的。伪造证书极其困难
被篡改
请求或响应在传输途中, 遭攻击者拦截并篡改内容的攻 击称为中间人攻击(Man-in-the-Middle attack, MITM)
HTTP协议虽然有确认完整性的办法,但是并不便捷可靠。因为如果MD5本身被改写,用户是无感知的
HTTPS
HTTP + 加密 + 认证 + 完整性保护 = HTTPS
与SSL组合使用的HTTP被称为HTTPS(HTTP Secure或者HTTP over SSL)
HTTPS并不是应用层的新协议。HTTP通信接口部分用SSL和TLS协议代替而已。
秘钥加密
-
共享秘钥加密(对称加密)(速度快)
加密和解密用同一个秘钥。但是难点在无法安全传输秘钥。任何人拿到秘钥都可以破解密码。
-
公开秘钥加密(非对称加密)(SSL采用)
有两个秘钥。一把叫做私有秘钥(private key),另一个叫做公开密钥(public key)
发送方使用公开秘钥加密后,接收方使用私有秘钥进行解密。
-
混合加密(HTTPS采用)
HTTPS采用共享秘钥和公开秘钥并用的加密机制。
在会话开始,使用非对称加密传递对称加密的秘钥,后双方使用对称加密的秘钥进行通信。
证明公开秘钥的证书
公开密钥加密的问题是,如何证明公开秘钥是真的公开密钥。(感觉有点套娃)
解决上述问题可以使用数字证书认证机构和其相关机构颁发的公开密钥证书。
SSL和TLS
TSL是以 SSL为原型开发的协议, 有时会统一称该协议 为 SSL。 当前主流的版本是 SSL3.0 和 TLS1.0。
Https比HTTP慢2-100倍。
- 一个是通信慢,另一种指消耗大量CPU和内存资源
- 网络负载大概慢2-100倍。除了TCP连接和HTTP请求,还要进行SSL通信
对此并无根本性的解决办法。因此如果是非敏感信息则使用HTTP通信,否则使用HTTPS。
另外,没有全面使用HTTPS也有一部分原因是购买证书也是一笔开销。
TCP握手丢失问题