第一章HTTP概述、第二章URL与资源
HTTP(Hypertext Transfer Protocol, 超文本传输协议)
MIME(Multipurpose Internet Mail Extension, 多用途因特网邮件扩展)
URI(Uniform Resource Identifier, 统一资源标识符)
URL(Uniform Resource Locator, 统一资源定位符)
方案://服务器位置/路径
http、mailto、ftp、rtsp
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
URN(Uniform Resource Name, 统一资源名)
PURL(Persistent Uniform Resource Locators, 永久统一资源定位符)
TCP(Transmission Control Protocal, 传输控制协议)
无差错,按顺序,未分段(任意时刻任意尺寸)
IP(Internet Protcol, 网际协议)
DNS(Domain Name Service, 域名服务器)
主机名转换为IP地址
没有端口号默认80
协议版本
- HTTP/0.9
只支持GET,不支持多媒体类型MIME、各种HTTP首部
- HTTP/1.0
各种HTTP首部、额外的方法、多媒体类型
- HTTP/1.0+
持久连接keep-alive、虚拟主机、代理
- HTTP/1.1
矫正、优化性能
- HTTP-NG(又名HTTP/2.0)
大幅优化
代理
缓存
网关
隧道
Agent代理
第三章HTTP报文
* CRLF: 回车 /r 换行 /n
报文流
流入(inbound)
流出(outbound)
下游(downstream)报文发送者都在接受者上游
报文的组成(保温室简单的格式化数据块)
起始行(start line) HTTP/1.0 200 OK
首部块(header) Content-type: text/plain
Content-length: 19
主体(可选的)包含数据的 Hi! I'm a message!
报文分两类:请求报文、响应报文
请求报文(request message)
<method> <request-URL> <version>
<headers> 零个或多个,
<entity-body>
响应报文(reponse message)
<version> <status> <reason-phrase>
<headers>
<entity-body>
起始行
方法
GET: HTTP/1.1实现
HEAD: 与GET类似,但是服务器响应中只返回首部
PUT:
POST:
TRACE: 主要用于诊断
OPTIONS:
DELETE:
状态码
100~199:信息性状态码
200~299:成功状态码
300~399:重定向状态码
If-Modified-since:Friday, Oct 3 1997 02:16:00 GMT
400~499:客户端错误状态码
500~599:服务器错误状态码
首部
通用首部:出现在请求和响应
请求首部:只出现请求
Accept首部:Accept、Accept-Charset、Accept-Encoding、Accept-Language
条件请求首部:expect、If-Match、If-Modified-Since、If-None-Match、
响应首部:只出现响应
实体首部:描述实体长度和内容,或者资源自身
HTTP/0.9 没有实体首部
实体缓存首部:ETag、Expires、Last-Modified
扩展首部:没有定义的首部
第四章HTTP连接管理
TCP连接
* 一旦建立连接,客户端与服务器的报文永远不会丢失、受损或失序
* 是可靠连接,按序无差错地承载HTTP数据
TCP流是分段的、由IP分组传送
每个IP分组包括:
一个IP分组首部(一般20字节)
一个TCP段首部(一般20字节)
一个TCP数据块(0个或多个字节)
保持TCP连接持续不断运行
TCP连接通过4个值识别,唯一定义一条连接
<源IP地址、源端口号、目的IP地址、目的端口号>
性能聚焦区域
* TCP连接建立握手
1)SYN
2)SYN + ACK
3)ACK + 发送数据
* TCP慢启动拥塞控制
* 数据聚集的Nagle算法
* 用于捎带确认的TCP延迟确认算法
* TIME_WAIT时延和端口耗尽
Connection首部
* HTTP首部字段名,列出了只与此连接有关的首部
* 任意标签值,用于描述此连接的非标准选项
* 值close,说明操作完成后需要关闭持久连接
提高HTTP的连接性能
* 并行连接:通过多条TCP连接发起并发的HTTP请求
* 持久连接:重用TCP连接,以消除连接及关闭时延
* 管道化连接:通过共享的TCP连接发起并发的HTTP请求
* 复用的连接:交替传送请求和响应报文
持久连接
* HTTP/1.0+ Keep-Alive
* HTTP/1.1 persistent
HTTP/1.0 Keep-Alive
请求首部添加Connection: Keep-Alive首部,如果服务器保持打开状态,响应中添加相同首部,如果不支持,响应就没有Connection: Keep-Alive首部,逐跳首部,不应该沿着链路向下传
* Keep-Alive并不是默认使用,必须加入Connection: Keep-Alive首部激活keep-alive连接
* Connection: Keep-Alive必须随所希望保持连接的报文一起发送,没有发送Connection: Keep-Alive首部,服务器就会在请求之后关闭连接
* 通过响应报文是否有Connection: Keep-Alive首部,客户端可以判断服务器请求之后是否会关闭连接
* 实体部分必须有正确的Content-Length,有多媒体类型,或者用分块传输编码的方式进行编码,才可以将连接保持打开状态
* 代理和网关必须执行Connection首部规则,将报文转发出去或者缓存之前,删除在Connection首部命中命名的所有首部字段以及Connection首部自身
* 不应与无法确定是否支持Connection: Keep-Alive首部的代理服务器建立keep-alive连接,防止出现哑代理问题
1)哑代理导致请求挂起
2)现代代理绝对不能转发Connection首部和Connection值中的首部
比如:Connection: Keep-Alive
Keep-Alive: max=5, timeout=120
* 技术上,应该忽略所有来自HTTP/1.0设备的Connection首部字段(包括Connection: Keep-Alive),因为他们可能是老代理服务器误转发的
* 客户端做好重试请求的准备
Keep-Alive选项
Keep-Alive首部是可选的,但是必须有Connection: Keep-Alive首部才可以使用
Connection: Keep-Alive
Keep-Alive: max=5, timeout=120
timeout:响应首部发送,估计了服务器希望将连接保持活跃状态的时间,不是承诺值
max:响应首部发送,估计了服务器还希望为多少个失误保持活跃状态,不是承诺值
插入Proxy-Connection
HTTP/1.1持久连接
停止了对keep-alive连接的支持,持久连接(persistent connection)的改进型取代
与HTTP/1.0+的keep-alive不同,persistent默认情况是激活的,除非特别指明,否则HTTP/1.1假定所有连接都是持久的,HTTP/1.1应用必须向报文显式添加Connection:close首部,才能关闭
* 发送了Connection:close首部之后,客户端无法再那条链路上发送更多请求
* 如果不想在连接上发送其他请求,就要在最后一条请求中添加Connection:close首部
* 只有当连接上所有报文都有正确的、自定义报文长度时,(实体主体长度应和Content-Length一致;用分块传输编码方式编码)连接才能持久连接
* HTTP/1.1的代理必须能够分别管理与客户端和服务器端的持久连接——每个持久连接都只适用于一跳传输
* HTTP/1.1代理服务器不该与HTTP/1.0客户端建立持久连接
* HTTP/1.1设备可以在任意时刻关闭连接
* HTTP/1.1应用必须能够从异步的关闭中恢复出来,客户端应该重试这条请求,只要不会产生副作用
* 除非重复请求会发生副作用,客户端必须重新发起请求
* 一个客户端对任何服务器或者代理只能维护2条持久连接,防止过载。代理可能需要更多到服务器的连接,所以如果有N个用户访问服务器,代理最多要维持2N跳到任意服务器或者父代理的连接
管道化连接
* 如果HTTP客户端无法确认连接时持久的,就不该使用管道
* 必须按照与请求相同的顺序回送HTTP响应
* HTTP客户端必须做好连接会在任意时刻管理的准备,还要准备重发
* HTTP客户端不应该管道化的范式发送会产生副作用的请求(POST)
连接关闭容限、重试以及幂等性
* 如果一个事务执行一次还是很多次得到的结果都相同,这个事务就是幂等的
*