HTTP协议详解

标签: 协议与规范

保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/25/ )。

1 简介

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。HTTP协议用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

图片

1.1 工作流程

一次HTTP操作称为一个事务,其工作过程可分为四步:

  1. 首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
  2. 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
  3. 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
  4. 客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。 如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。

1.2 HTTP协议特点

2 HTTP1.1的新机制

HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。

2.1 持久连接

1.1 版的最大变化,就是引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。

2.2 管道机制

1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。

举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。

但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为”队头堵塞”(Head-of-line blocking)。

为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。

2.3 Content-Length字段

一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是Content-length字段的作用,声明本次回应的数据长度。

Content-Length: 3295

上面代码告诉浏览器,本次回应的长度是3295个字节,后面的字节就属于下一个回应了。

在1.0版中,Content-Length字段不是必需的,因为浏览器发现服务器关闭了TCP连接,就表明收到的数据包已经全了。

使用Content-Length字段的前提条件是,服务器发送回应之前,必须知道回应的数据长度。对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用”流模式”(stream)取代”缓存模式”(buffer)。

因此,1.1版规定可以不使用Content-Length字段,而使用”分块传输编码”(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding字段,就表明回应将由数量未定的数据块组成。

Transfer-Encoding: chunked

每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。

2.4 其他改进

接下来,我们详细介绍1.1版本的相关规范。

3 客户端请求

发出的请求具体格式如下:

图片

示例:

图片

发出的请求信息包括以下几个:

3.1 请求行

例如:GET /pagead/js/r20160511/r20160513/expansion_embed.js HTTP/1.1, 分别说明了请求方法、请求地址、HTTP协议版本号。

3.1.1 请求方法

Method名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。

HTTP协议没有对传输的数据和URL长度进行限制,但特定浏览器和服务器对URL长度有限制, 因此对于GET提交时,传输数据就会受到URL长度的限制;由于POST操作不是通过URL传值,理论上数据长度不受限。

3.1.2 HTTP协议版本

3.1.3 URL

url的格式如下: schema://host[:port#]/path/.../[;url-params][?query-string][#anchor] 有以下的组成部分:

举例子:

图片

3.2 请求首部

请求首部包含众多的可配置项:

4 服务器回应

与HTTP请求类似,HTTP响应也是由三个部分组成,分别是:状态行,回应首部,回应正文。

图片

示例:

图片

4.1 状态行

主要包括:HTTP版本号,状态码。

各个状态码的意义:

一些常见的状态码:

4.2 回应首部

可选项也非常多:

4.3 回应正文

即这次服务器返回的内容信息,可能是压缩的。相关压缩协议等均在回应首部进行了说明。

5 HTTPS

HTTP在安全方面存在以下的缺点:

HTTPS比HTTP多了TLS/SSL层,即HTTP是直接和TCP打交道。而加入新的一层后,HTTP先和TLS/SSL层打交道,然后TLS/SSL层在和TCP层打交道。这样就实现了加密。

图片

5.1 TLS与SSL

TLS(Transport Layer Security 传输层安全)/SSL (Secure Sockets Layer安全套接层), 是介于传输层TCP和应用层HTTP之间的一层安全协议,TLS/SSL 具有身份验证、信息加密和完整性校验的功能,目的是保障客户端到服务端之间连接的安全性。

SSL(Secure Socket Layer,安全套接字层):1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。

TLS(Transport Layer Security,传输层安全):其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。

因此两者功能上是一样的。

TLS/SSL发展历史:

5.2 证书产生

图片

图片

持有EV SSL证书的web网站浏览器地址栏处的背景是绿色的.点击后可以查看详情

图片

5.3 工作过程

SSL/TSL握手的作用是身份验证和协商密钥。密钥交换是为了在不安全数据通道中产生一个只有通信双方知道的对称加密 Session Key。身份认证的目的是确保连接到拥有网站私钥的合法服务器。

TLS/SSL握手主要过程如下:

图片

因为HTTP本身存在的安全性问题,目前已不推荐使用。谷歌发布的Chrome浏览器从 68版本开始将非HTTPS网站被显著标记为“不安全(Not Secure)”。因此,及时将网站升级为HTTPS十分必要。

本文首发于个人知乎:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。

作者书籍推荐