目录
第一章 HTTP概述
第二章 URL与资源
第三章 HTTP报文
第四章 连接管理
第一章 HTTP概述
1、POST和PUT的区别
- POST:将客户端数据发送到一个服务器网关应用程序
- PUT:将来自客户端额数据存储到一个命名的的服务器资源中
2、HTTP报文:格式是纯文本,不是二进制代码,可以很方便的调试和拓展。报文分为请求报文和响应报文,格式很类似,主要包含以下三个部分:起始行、首部字段、(空行)、主体。
3、HTTP协议:应用程协议,网络通信的底层细节由TCP/IP传输协议实现,保证无差错、按序传输、流式数据(可以在任何时刻以任意尺寸将数据发送出去)
4、HTTP协议版本:0.9版本有很严重的设计缺陷,只应该用于老客户端的交互,只支持GET请求,不支持多媒体内容的MIME类型。1.0是一个广泛使用的版本,添加了版本号、各种HTTP首部,一些额外的方法以及多媒体对象的处理,使得包含生动图片的WEB页面和交互表格成为可能。1.0+支持keep-alive长连接、虚拟主机支持、代理连接。1.1是当使用的版本,引入重要的性能优化删除一些不好的特性。2.0重点关注的是性能的大幅优化以及更强大的服务逻辑远程执行框架。
5、WEB的结构组件
- 代理:位于客户端和服务端之间的HTTP实体,接受所有客户端的HTTP请求转发给服务端,可以对请求进行修改。对于用户客户端来说这样的应用程序就是代理,比如可以进行客户端下载资源检测等。
- 缓存:HTTP的仓库,使常用的页面副本可以保存在离客户端更近的地方,一种特殊的HTTP代理服务器,将客户端一次请求访问的资源缓存起来,接下来的请求可以从缓存中取出来。
- 网关:连接其他应用程序的WEB服务器,一种特殊的服务器,作为其他服务器的中间实体使用,通常用于将HTTP流量转换成其他协议。
- 隧道:对HTTP通信报文进行盲转发的特殊代理,建立起来之后,就会在两条连接之间对原始数据进行盲转发的HTTP应用程序,通常会在一条或者多条HTTP连接上转发非HTTP数据,转发时候不会窥探数据,常见的一种用途就是通过HTTP链接承载加密的安全套接字层(SSL Secure Sockets Layer)流量,这样SSL流量就可以穿过只允许Web流量通过的防火墙了。如HTTPS连接建立的过程是通过HTTP请求先建立一条HTTP/SSL隧道,然后在HTTP信道上传输加密的SSL流量。
- Agent代理:发起自动HTTP请求的半智能WEB客户端,代表用户发送HTTP请求的客户端程序,如WEB 浏览器。
第二章 URL与资源
1、URL字符集:默认的计算机系统字符集都通常倾向于以英语为中心。很多计算机使用的是US-ASCII字符集,使用7位二进制码表示英文打字机提供的大多数按键和少数不可打印控制字符(用于文本格式和硬件通知)。ASCII码历史悠久,可移植性好,但是能表示的语言太少,因此需要通过一种编码机制,通过转义表示不安全字符。例子
- “~” :120(0x7E)
- “空格” :32(0x20)
- “%” :37(0x25)
在URL中,有几个字符被保留起来,有着特殊的含义,%、/、.、..、#、?、;、:、$,+、@&=、{}、|、\、^、~、[]、<>、0x00-0x1f、0x7f、>0x7f
等,对于某些传输协议是支持非安全字符的。
2、常见的WEB方案
- http
- https
- mailto:指向的是Email地址,与其他方案都不太通,他并不指任何可以直接访问的对象,如
mailto:joe@joes-hardware.com
- ftp:作为一种数据访问方案使用
- rtsp、rtspu:RESP URL 是可以通过实时流传输协议解析的音、视频媒体资源标识符。方案中的u指的是使用UDP来获取资源的。
- file:一台主机上可以直接访问的文件
- news:访问特定的文章或者新闻组
- telnet:交互式业务,通过telnet访问资源
第三章 HTTP报文
1、报文的组成部分:三个部分分别是对报文描述的起始行start line,包含属性的首部header,可选包含数据的主体body部分。起始行和首部是由行分隔符的ASCII码,每行都以一个由两个字符组成的行终止序列作为结束(回车符ASCII是13,换行符ASCII码是10),主体可以包含文本数据与二进制数据,也可以为空,首部的Content-Type说明了主体是什么形式。一个报文可以由0个或多个首部。
2、常用的HTTP方法
- GET
- HEAD:从服务器获取响应报文的首部,可以用于检测资源的情况,类型以及是否存在。
- POST:向服务器发送需要处理的数据
- PUT:向服务器发送需要存储的数据
- TRACE:对可能经过代理服务器传送到服务器上的报文进行追踪,TRACE请求主要用于诊断,用于验证请求是否如愿的穿过请求、响应链,请求中不能带有实体的body部分,响应的主体body中是服务器收到请求的精确副本。
- OPTIONS:请求服务器告知支持的各种功能,可以是方法,或者对某些特殊资源支持哪些方法。 出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域)。参考:https://www.jianshu.com/p/5cf82f092201
- DELETE
3、常见的HTTP状态码:主要被分为5大类
- 100-199信息类状态码
- 100-Continue状态码,客户端如果想要在发送包含body的报文之前查看服务器是否会接受他,可以事先发一个携带值为100 Coninue 的 Expect 请求,服务端必须针对这个请求响应,是否接受客户端发送的报文。
- 200-299成功状态码
- 200-OK表示请求没问题,实体的主体部分包含了所请求的资源
- 201-Created用于创建服务器对象的请求如PUT,响应的实体主体部分中应该包含了引用已创建资源的URL保存在Location字段。
- 202-Accepted请求已被接受,但服务器还未执行任何动作,不能保证服务区会完成这请求。
- 203-Non-Authoritative Information实体首部包含的信息不是来自于源端服务器,而是来自资源的一份副本,并没对资源的元数据进行校验。
- 300-399重定向状态码:告知客户端使用替代位置来访问他们所感兴趣的资源,配合可选的Location首部告诉客户端资源以被移走。
- 300-Multiple Choices客户端请求一个实际指向多个资源的URL时会返回这个状态码,比如服务器上某个HTML不同的语言版本,返回这个状态码会带上一个选项列表,这样用户可以选择。
- 301-Moved Permanently:请求的URL移除,响应的Location首部应该包含资源所处的URL。
- 302-Found:类似301,但是在HTTP1.0客户端发起一个POST请求,收到302之后会接受Location首部指定的重定向URL,并向那个URL发送一个GET请求,而不是像原始请求中发起POST请求。但是HTTP1.1规定使用303状态码实现上述行为,为了避开这个问题,HTTP1.1规定使用307代码取代302进行临时重定向。
- 305-Use Proxy:用来说明必须使用一个代理访问资源,代理的位置使用Location给出。
- 400-499客户端错误状态码
- 400错误请求
- 401未认证
- 403服务端禁止
- 404资源找不到
- 405方法不允许
- 406服务端不接受此类型body
- 408客户端处理时间长,服务端关闭连接
- 500-599服务器错误状态码
- 500服务器内部错误
- 501客户端发起的请求超出服务端的能力范围
- 502网关无法访问
- 503服务暂时不可用,可以在响应中包含一个Retry-After首部告知什么时候可用。
4、HTTP首部信息,如
- 通用首部:请求报文、响应报文都可以拥有
- Connection:比如keep-alive长连接就是设置在这块。
- Date:报文创建的时间
- MIME-Version:给出了发送端使用的MIME版本
- Trailer:如果报文采用了分块传输编码,就可以用这个首部列出位于报文
- Transfer-Encoding:报文的编码方式
- Update:发送端可能想要升级使用的新版本或者协议
- Via:显示报文经过的中间节点(代理、网关)
- 请求首部:请求报文特有的,他们为服务器提供一些额外的信息
- Accept:比如客户端希望接受什么类型的数据
- Referer:提供了包含当前请求URL的文档URL
- User-Agent:将发起请求的应用程序名称告知服务器
- Expect、If-Match、If-Modified-Since、If-Range和Range等条件请求首部:If-Range表示允许对文档的某个范围进行条件请求配合Range来限制资源指定范围。
- Authorization、Cookie:安全认证请求首部,Cookie是客户端向服务端传送的一个令牌,并不是真正的安全首部,但是确实隐藏了安全功能。
- Max-Porward、Proxy-Authorization、Proxy-Connection代理请求首部,供代理使用的属性信息。
- 响应首部:响应报文特有的,以便为客户端提供信息
- Server:比如客户端在根哪种类型的服务器进行交互
- Age:响应持续的时间(从最初创建开始)
- Retry-After:如果资源不可用的话,在此日期或时间重试
- Warning:比状态码后面的原因短语更详细的一些警告报文
- Accept-Ranges、Vary协商首部
- 实体首部:描述HTTP报文的负荷,提供实体及其内容的大量信息,在请求报文和响应报文中都会存在。
- Allow:列出可以对此实体执行的请求方法
- Location:告知客户端实体实际存储在那个URL上去
- Content-xxx:主体body相关,如Content-Type、Content-Ecoding等
- ETag-资源版本标识符、Expires-缓存失效时间、Last-Modified-实体最后一次被修改的时间:实体缓存首部相关。
- 扩展首部:非标准的首部,由应用程序开发者创建,由HTTP应用程序转发
- 通用缓存首部:HTTP/1.0引入第一个允许HTTP应用程序缓存对象本地副本的首部,如Pragma允许缓存,HTTP/1.1改成了Cache-Controller
第四章 连接管理
1、TCP连接:世界上几乎所有的HTTP通信都是由TCP/IP承载的,TCP/IP是全球计算机和网络设备都使用的常用分组交换网络分层协议集。HTTP连接实际上就是TCP连接及其使用规则,TCP提供一条可靠的比特流传输管道,TCP的数据是通过名为IP分组(IP数据报)的小数据块发送的,可以将HTTP理解 HTTP over TCP over IP 这个协议栈,HTTPS就是在HTTP和TCP之间插入一个TLS、SSL的密码加密层。
2、TCP套接字API:套接字API允许用户创建TCP的端点数据结构,将这些端点与远程服务器的TCP端点进行连接,并对数据流进行读写,隐藏了底层网络协议和握手细则,以及TCP数据流与IP分组之间的分段和重装细节。
3、TCP性能:HTTP紧挨着TCP,位于其上层,所以HTTP事务的性能很大程度上取决于底层TCP通道的性能。
4、HTTP事务的时延:与建立TCP连接以及传输请求和响应报文的时间相比,事务处理的时间可能是很短的,除非客户端或者服务端超载或正在处理复杂的动态资源,否则HTTP时延就是有TCP网络时延造成的。HTTP事务的时延主要由一下几种原因,主要取决于硬件速度,网络和服务器的负载,请求和响应报文的大小以及客户端和服务端之间的距离,TCP协议的复杂度同样也会对时延产生巨大的影响。
- 客户端首先需要根据URI确定Web服务器的IP地址和端口号,如果最近没有对URI中的主机进行访问,通过DNS解析系统将URI中的主机名转换成一个IP地址可能需要花费数10s的时间。
- 在建立TCP连接通道的时候需要三次握手,会有建立时延,这个值通常只有一两秒中,如果数百个HTTP事务,这个值也会快速叠加上去。
- 报文的传输时延
5、TCP相关时延
- TCP三次握手建立连接:现在的TCP栈都允许在客户端第三次握手发送的ACK确认分组中包含需要的真实数据。
- TCP慢启动拥塞机制:防止网络拥塞的机制,由于这种机制,新连接的传输速度会比已经交换过一定数据的、已经平稳的连接慢一些,所以HTTP中有一些可以重用现存连接的工具。
- 数据聚集的Nagle算法:TCP有一个数据流接口,应用程序可以通过他将任意尺寸的数据放入TCP栈(即使每次只有一个字节也可以)但是TCP段中包含40个字节的首部标记和首部,如果TCP段中的有用数据太少,网络的性能就会严重下降。Nagle算法试图在发送一个分组之前,将大量的TCP数据绑定在一起,以提高网络效率。Nagle算法鼓励发送全尺寸(LAN上最大的尺寸分组是1500字节,在因特网上是几百字节)的TCP段,如果其他分组仍然在传输过程中,就将那部分数据缓存起来,只有当挂起的分组被确认,或者缓存中积累够了足够发送一个全尺寸分组数据的时候,才会将缓存的数据发送出去。Nagle算法会引发几种HTTP性能问题,首先,小的HTTP报文可以无法填满一个分组,可能会因为等待那些永远不会到来的额外数据产生时延,其次,Nagle算法会阻止数据的发送,直到有确认分组抵达为止,但确认分组自身自身会被延迟确认算法延迟100-200毫秒,可以通过参数TCP_NODELAY禁用Nagle算法,如果这麽做,最好确定向TCP段写入大块数据。
- 用于捎带确认的TCP延迟确认方法:由于因特网自身无法确保可靠的分组传输(因特网路由器超负载的话可以随意丢弃分组),因此TCP实现了基于滑动窗口的确认机制,现在很多TCP栈都实现了一种"延迟确认"算法,延迟确认算法会在一个特定的窗口时间(通常是100~200ms)内将输出确认放在缓冲区,已寻找能够捎带他的输出报文分组,也就是把去确认信息和输出的报文信息放一块,如果在那个时间没有输出数据分组,就会将确认信息放在单独的分组中传送。但是HTTP具有双峰特征的请求-应答行为降低了捎带信息的可能,导致确认报文一直在缓存中等待,通常延迟确认算法会引入相当大的时延,可以调整或禁止延迟确认算法。
- TIME_WAIT时延和端口耗尽:当某个客户端TCP端点关闭TCP连接时候,会在内存中维护一个小的控制块,用来记录最近所关闭连接的IP、port,这类信息只会维护较短的一段时间,通常是所估计最大分段使用期间的两倍,称为2MSL(通常为两分钟),保证客户端最后发送的ACK能够到达服务器,帮助其正常关闭。
6、HTTP连接的处理
- 常被误解的Connection首部
- 串行事务处理时延,假如每次请求资源都需要建立一个请求,那么连接时延和慢启动时延就会叠加起来,会造成速度很慢,几种现存和新兴的方法可以提高HTTP的连接性能,
- 并行连接:通过多条TCP连接发起并发的HTTP请求资源。即使并行连接的速度可能会更快,但并不一定总是更快,客户端的网络带宽不足导致多个HTTP事务竞争带宽,这样带来的性能提升很小。而且打开大量的连接会消耗很多的内存资源,从而引发自身的性能问题,比如Web服务器需要处理大量的用户连接请求,假如100个用户同时发请求,每个用户打开100个连接,服务器就要负责处理1w个连接,这会造成服务器性能严重下降,对高负荷的代理来说也是同样如此。因此浏览器一般会限制并行连接的数量为一个较小的值(通常是4个),服务器可以随意关闭来自特定客户端的超量连接。
- 持久连接:重用TCP连接,以消除连接及关闭时延。站点局部性原理指的是用户可能再一段时间内更多访问某站点上的资源,因此再HTTP1.0允许HTTP设备再事务处理结束之后将TCP连接保持打开状态,比如keep-alive支持长连接字段,HTTP1.1的 persistent 连接称为持久连接,可以一定程度避免建立连接、慢启动机制的时延。但是管理持久连接时要特别小心,不然就会累计出大量的空闲连接,耗费本地以及远程客户端和服务器上的资源。使用keep-alive首部是将连接保持在活跃状态,发出keep-alive请求之后,客户端和服务端并不一定会同意进行keep-alive会话,如果同意,需要在响应头中带上keep-alive字段,他们可以在任意时刻关闭空闲的keep-alive连接,另外可以通过选项调节行为,比如timeout参数是响应头keep-alive存在时配置的,他估计服务器希望将连接保持在活跃状态的时间,比如max是在keep-alive存在响应首部发送的,他估计了服务器还希望多少个事务保持此连接的活跃状态。
- 管道化连接:通过共享的TCP连接发起并发的HTTP请求。
- 复用的连接:交替传送请求和响应报文。