HTTP 即超文本传输协议,是 Web 的应用层协议。HTTP 由两个程序实现,一个客户程序和一个服务器程序,客户程序和服务器程序运行在不同的端系统中,通过交换 HTTP 报文进行会话。HTTP 定义了这些报文的结构以及客户和服务器进行报文交换的方式,当用户请求一个 Web 页面时,浏览器向服务器发出对该页面中所包含对象的 HTTP 请求报文,服务器接收到请求并用包含这些对象的 HTTP 响应报文进行响应。
HTTP 使用 TCP 作为它的支撑运输协议,HTTP 客户首先发起一个与服务器的 TCP 连接,一旦连接建立,该浏览器和服务器进程就可以通过套接字访问 TCP。客户端的套接字接口是客户进程与 TCP 连接之间的门,服务器端的套接字接口则是服务器进程与 TCP 连接之间的门。客户向它的套接字接口发送 HTTP 请求报文并从它的套接字接口接收 HTTP 响应报文,类似的,服务器从它的套接字接口接收 HTTP 请求报文并向它的套接字接口发送 HTTP 响应报文。一旦客户向它的套接字接口发送一个 HTTP 请求报文,该报文就脱离了客户控制并进入 TCP 的控制,TCP 为 HTTP 提供可靠的数据传输服务,因此一个客户进程发出的每个 HTTP 请求报文最终都能完整地到达服务器,服务器进程发出地每个 HTTP 响应报文最终也可以完整地到达客户。这里体现了分层体系结构的优点,HTTP 协议不需要担心数据丢失,也不需要关注 TCP 从网络的数据丢失和乱序中如何恢复。
HTTP 是一种无状态的协议,服务器向客户发送被请求的文件,而不存储任何关于该客户的状态信息。假如某个客户在短时间内连续两次请求同一个对象,服务器并不会因为刚刚为该客户做出了响应就不再响应,而是重新进行响应。
依据每个请求/响应对经过一个单独的 TCP 连接还是相同的 TCP 连接发送,可以将连接划分为非持续连接和持续连接。HTTP 默认使用持续连接,但是也可以配置成使用非持续连接。
非持续连接
使用非持续连接时,从服务器向客户传送一个包含了一个 HTML 文件和 10 个 JPG 对象的 Web 页面步骤:
① HTTP 客户进程在端口号 80 发起一个到服务器的 TCP 连接,并经它的套接字向服务器发送一个 HTTP 请求报文。② HTTP 服务器进程经它的套接字接收请求报文,从其存储器中检索出请求对象,在一个 HTTP 响应报文中封装对象,并通过套接字向客户发送响应报文。③ HTTP 服务器进程通知 TCP 断开该 TCP 连接,直到 TCP 确认客户已经完整接收到响应报文才会实际断开连接。④ HTTP 客户接收到响应报文,客户从报文中提取出 HTML 文件,得到多个 JPG 图像的引用,并对每个引用的 JPG 图像对象重复前三个步骤。
每个 TCP 连接会在服务器发送一个对象后关闭,即该连接并不为其他的对象而持续下来。每个 TCP 连接只传输一个请求报文和一个响应报文,假如请求一个 HTML 文件和其中包括的 10 个 JPG 图像就要产生 11 个 TCP 连接。
在非持续连接中,每次请求文件到接收响应大约需要花费两个 RTT 加上服务器传输文件的时间,RTT 就是往返时间,指一个短分组从客户到服务器然后再返回客户所发送的时间。其中三次握手的前两个部分占用一个 RTT,三次握手的第三个确认部分向服务器发送了请求报文,服务器接收到之后做出响应,这用去了另一个 RTT。
持续连接
非持续连接有很多缺点。第一,必须为每个请求的对象建立和维护一个新的连接,对于每个连接,在客户和服务器中都要分配 TCP 的缓冲区和保持 TCP 变量,这给 Web 服务器带来了很大负担。第二,每一个对象需要消耗两倍的 RTT,一个用于创建 TCP,一个用于请求和接收对象。
在 HTTP1.1 中使用了持续连接,服务器在发送响应后保持该 TCP 连接打开。在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。在使用持续连接的情况下,请求一个完整的 Web 页面可以使用单个持续的 TCP 连接,例如之前所说的包含一个 HTML 文件和 10 个 JPG 对象的 Web 页面就只需要一个 TCP 连接而不是 11 个。
HTTP 报文有两种,分为请求报文和响应报文。
请求报文
HTTP 请求报文的第一行叫做请求行,其后继的行叫做首部行。请求行有三个字段,包括方法、URL 和 HTTP 版本。方法包括了 GET、POST、HEAD、PUT 和 DELETE 等。绝大部分的 HTTP 请求报文使用 GET 方法,当使用 GET 方法时,在 URL 字段中会带有请求对象的标识。
首部行指明了对象所在的主机,其实已经存在 TCP 连接了,但是还需要首部行提供主机信息,这时 Web 代理高速缓存所要求的。通过包含 Connection:close
的首部行,可以告诉服务器不要麻烦地使用持续连接,它要求在发送完响应后就关闭连接。User-agent
可以用来指明用户代理,即向服务器发送请求的浏览器类型,服务器可以有效地为不同类型的用户代理发送实际相同对象的不同版本。
在首部行之后有一个空行,后面跟着的是实体。使用 GET 方法时实体为空,而使用 POST 方法时才会使用实体。当用户提交表单时,HTTP 客户通常使用 POST 方法,使用 POST 方法时用户仍可以向服务器请求一个 Web 页面,但 Web 页面的特定内容依赖于用户在表单字段中输入的内容。如果使用 POST 方法,则实体中包含的就是用户在表单字段的输入值。不管表单不是必须使用 POST 方法,也可以使用 GET。
HEAD 方法类似于 GET,当服务器收到一个使用 HEAD 方法的请求时,将会用一个 HTTP 报文进行响应,但是并不返回请求对象。通常开发者使用 HEAD 方法进行调试跟踪。PUT 方法常用于上传对象到指定的 Web 服务器上指定的目录,DELETE 方法允许用户或应用程序删除 Web 服务器上的对象。
响应报文
响应报文包括状态行、首部行和实体。状态行有三个字段,协议版本、状态码和对应的状态信息。实体是报文的主要部分,即所请求的对象本身。
服务器通过首部行来告诉浏览器一些信息。 Connection:close
可以告诉客户发送完报文后将关闭该 TCP 连接。Date
是首部行指示服务器发送响应报文的日期和时间,这个时间不是对象创建或修改的时间,而是服务器从它的文件系统中检索到该对象,将该对象插入响应报文并发送的时间。Server
指明了服务器的类型,类似于请求报文中的 User-agent
。
状态码及其相应的短语指示了请求的结果,一些常见的状态码和相关短语如下:
状态码 | 短语 | 含义 |
---|---|---|
200 | OK | 成功响应 |
301 | Moved Permanently | 请求的对象已经被永久转移了,新的 URL 定义在响应报文的 Location 首部行,客户将自动获取新的 URL。 |
302 | Found | 与301类似,但资源只是临时被移动,客户端应继续使用原有 URL。 |
400 | Bad Request | 一个通用的差错代码,标识该请求不能被服务器理解。 |
403 | Forbidden | 服务器理解客户端的请求,但是拒绝执行。 |
404 | Not Found | 被请求的文档不在服务器上,有可能因为请求 URL 出错。 |
405 | Method Not Allowed | 客户端中请求的方法被禁止,例如限制 POST 方式但使用了 GET 访问。 |
500 | Internal Server Error | 服务器内部错误,无法完成请求。 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应。 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。 |
504 | Gateway Timeout | 充当网关或代理的服务器,未及时从远端服务器获取请求。 |
505 | HTTP Version Not Supported | 服务器不支持请求报文使用的 HTTP 协议版本。 |
HTTP 的无状态性简化了服务器的设计,并且提高了 Web 服务器的性能,使其可以同时处理大量的 TCP 连接。但是一个 Web 站点通常希望能够识别用户,可能是为了限制用户的访问,也可能为了把内容与用户身份关联起来,为此 HTTP 使用了 cookie,cookie 是一种客户端的会话技术,允许站点对用户进行追踪。
cookie 技术有四个组件:① 在 HTTP 响应报文中的一个 cookie 首部行。② 在 HTTP 请求报文中的一个 cookie 首部行。③ 在用户端系统中保留有一个 cookie 文件,并由用户的浏览器关联。④ 位于 Web 站点的一个后端数据库。cookie 的工作流程:当客户通过浏览器第一次访问某个站点时,该 Web 站点将产生一个唯一识别码,并以此作为索引在它的后端数据库中产生的一个表项。接下来服务器会用一个包含 Set-cookie
首部的 HTTP 响应报文对浏览器进行相应,当浏览器收到后将其添加到自己管理的 cookie 文件中,在下次访问该站点时,请求报文的首部行中就会包括这个识别码,尽管浏览器不知道客户是谁,但是可以确定是同一个客户进行了访问。
cookie 和 session 的区别:① cookie 只能存储 ASCII 码字符串,而 session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选session。② session 存储在服务器,而 cookie 存储在客户浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 cookie 中,可以将 cookie 值进行加密,然后在服务器进行解密。
Web 缓存器也叫代理服务器,它是能够代表初始 Web 服务器来满足 HTTP 请求的网络实体。Web 缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象副本。可以配置用户的浏览器,使得用户所有的 HTTP 请求首先指向 Web 缓存器。客户通过 Web 缓存器请求对象的步骤如下:
① 浏览器创建一个到 Web 缓存器的 TCP 连接,并向 Web 缓存器中的对象发送一个 HTTP 请求。② Web 缓存器进行检查,查看本地是否存储了该对象副本。如果有,Web 缓存器就向客户浏览器用 HTTP 响应报文返回该对象。③ 如果 Web 缓存器中没有该对象,它就打开一个与该对象的初始服务器的 TCP 连接,Web 缓存器在这个连接上发送一个请求并接受响应。④ Web 缓存器接收到响应后,在本地存储空间存储一份副本,并向客户的浏览器用 HTTP 响应报文发送该副本。
Web 缓存器既是服务器又是客户,当它接受浏览器的请求并响应时,它是一个服务器,当他向初始服务器发出请求并接收响应时,它是一个客户。在因特网上部署 Web 缓存器有两个原因,首先,Web 缓存器可以大大减少对客户请求的响应时间,特别是客户与初始服务器之间的带宽远低于客户与 Web 缓存器之间的带宽时更是如此。其次,Web 缓存器可以大大减少一个机构的接入链路到因特网的通信量,通过减少通信量,机构就不必基于增加带宽,可以降低费用。
HTTP 以明文的方式发送数据,不提供任何形式的数据加密,因此不安全。HTTPS 即 HTTP over SSL,在之前的 HTTP 传输上增加了 SSL 协议的加密能力,SSL 是安全套接字层,SSL 协议工作于传输层与应用层之间,为应用提供数据加密的服务。HTTPS 采用混合加密机制,使用非对称密钥传输对称密钥来保证传输过程的安全性,之后使用对称密钥进行通信来保证通信过程的效率。
在整个 HTTPS 的传输过程中,主要分为两部分:首先是 HTTPS 的握手,然后是数据的传输。前者是建立一个 HTTPS 的通道,并确定连接使用的加密套件及数据传输使用的密钥,而后者主要使用密钥对数据加密并传输。访问一个 HTTPS 的网站大致流程如下:
① 浏览器向服务器发送请求,请求中包括浏览器支持的 SSL 协议版本号和一些可选的加密算法。
② 服务器收到请求后,选择某种非对称加密算法,然后返回数字证书,包含了服务器的信息、加密公钥以及加密算法等。
③ 浏览器收到后,使用该证书的认证机构 CA 的公钥对该证书进行验证,验证成功后生产一个随机的秘密数,然后用服务器的公钥对秘密数进行加密并发送给服务器。
④ 服务器用自己的私钥解密后,使用该秘密数计算出一个对称会话密钥,以此作为加密信息并发送。
⑤ 当会话密钥产生完成后,就可以进行数据传输,所有数据通过该会话密钥进行对称加密。