一、概述

计算机网络体系结构分层

TCP/IP通信传输流

利用TCP/IP协议族进行网络通信,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收层从链路层往上走。

  1. 发送端在应用层(HTTP协议)发送一个请求某web页面的连接请求。
  2. 在传输层(TCP协议)把应用层受到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。
  3. 在网络层(IP协议)增加作为通信目的地的MAC地址后转发给链路层。
  4. 接收端的服务器在链路层接收到数据向上发送,当传输到应用层才能真正接收到由客户端发送过来的HTTP请求

  1. HTTP协议(超文本协议)用于从www服务器传输超文本到本地浏览器的传输协议。
  2. HTTP协议是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。
  3. 浏览器通过URL统一资源定位符网址,确定了要浏览的网页地址,提取代码后翻译成漂亮的网页。

二、HTTP 工作过程

HTTP通信机制是在一次完整的HTTP通信过程中,客户端与服务端之间完成下列7个步骤:

  1. 建立TCP连接:TCP与IP协议共同构造Internet,即著名的TCP/IP协议族。HTTP是比TCP更高层次的应用层协议,根据规则,只有底层协议建立之后,才能进行高层协议的连接,因此首先建立TCP连接。
  2. 客户端向服务器发送请求命令:GET/sample/hello.jsp HTTP/1.1
  3. 客户端发送请求头信息:客户端发送请求命令后,以头信息的形式向服务器发送一些别的信息,之后以空白行来通知服务器,已经结束了该头信息的发送。
  4. 服务器应答:HTTP/1.1 200 OK    协议版本号和响应码
  5. 服务器返回响应头信息:服务器也会随同响应向用户发送关于它自己的数据及被请求的文档
  6. 服务器向客户端发送数据:服务器发送头信息后,之后发送一个空白行来表示头信息的发送结束,接着以Content-Type响应头信息所描述的格式发送用户所请求的实际数据
  7. 服务器关闭TCP连接:一般情况下服务器返回给了客户端所请求的数据,就关闭TCP连接,但是如果客户端或者服务器在其头信息中加入了Connection:keep=alive,TCP连接在发送后将仍然保持打开状态,于是客户端可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络宽带。

三、HTTP 协议基础

  • 通过请求和响应的交换达成通信:首先从客户端开始建立通信,服务器在没有收到请求之前是不会发送响应的
  • HTTP是不保存状态的协议:协议自身不对请求和响应之间的通信状态进行保存,也就是HTTP协议对于发送和响应不做持久化处理,后续的Cookie技术可以保存通信状态。
  • 使用Cookie的状态管理:在请求和响应报文中写入Cookie信息来控制客户端的状态。Cookie会根据从服务端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie,当下次客户端再往服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送,服务端发现客户端发送的Cookie会检查究竟是哪个客户端发来的请求,然后对比服务上的记录,最后得到之前的状态信息。
  • 请求URI定位资源:URI定位网络资源
  • 告知服务器意图的HTTP方法(HTTP/1.1)
  • 持久连接:避免请求一个资源(包含多资源)造成无畏的TCP连接和断开,所以现在连接方法是只要任意一方没有明确提出断开连接,则始终保持TCP连接状态,旨在建立一次TCP连接后多次请求和响应的交互。HTTP/1.1 中,所有的连接默认都是持久连接
  • 管线化:以前发送请求需要等待并接收到响应后才能发送下一个请求。管线化技术出现之后,不用等待也可以发送下一个请求,做到了同时并行发送多个请求,而不需要一个接一个地等待响应了。

四、HTTP 协议报文结构

  • HTTP报文:用于HTTP协议交互的信息被称为HTTP报文。请求端被称作请求报文,响应端被称作响应报文,HTTP报文本身是由多行数据构成的字符串文本
  • HTTP报文结构:报文首部(服务器或客户端需处理的请求或响应的内容以及属性)和报文主体(应被发送的数据)。
  • 请求报文结构

请求报文:

请求行:用于请求的方法、URI、HTTP版本
首部字段:包含表示请求的各种条件和属性的各类首部,通用首部、请求首部、实体首部以及RFC里未定义的首部如Cookie等

响应报文:


状态行:协议版本、状态码、状态码的原因
响应首部字段:各种属性和属性值
主体:HTML

五、HTTP 报文首部之请求行、状态行

请求行:请求访问某台HTTP服务器上的/index.htm页面资源

GET /index.htm HTTP/1.1
Host:sample.com
  • GET 表示请求访问服务器的类型,称之为方法
  • /index.htm 指明了请求访问的资源对象,也叫做请求URI
  • HTTP/1.1 HTTP版本号,用来指示客户端使用的HTTP协议功能
状态行:
HTTP/1.1 200 OK
Content-Length:256

<html>
...
  • 开头的HTTP/1.1表示服务器对应的HTTP版本
  • 200 OK 表示请求的处理结果状态码和原因短语

六、HTTP 报文首部之首部字段(重点分析)

首部字段由首部--------字段名:字段值


首部字段类型:

  • 通用首部字段--------请求报文和响应报文两方都会使用的首部
  • 请求首部字段--------从客户端向服务端发送请求报文时使用的首部,补充了请求附加内容、客户端信息、响应内容相关优先级等信息
  • 响应首部字段-------从服务端向客户端返回响应报文时使用的首部,补充了响应的附加内容,也会要求客户端附加额外的内容信息
  • 实体首部字段-------针对请求报文和响应报文的实体部分使用的首部,补充了资源内部更新时间与实体有关的信息。

可用指令:

缓存请求指令:no-cache no-store


缓存响应指令:public private

警告:HTTP/1.1定义了7种警告

请求首部


响应首部


实体首部


Cookie



七、HTTP 响应状态码(重点分析)

HTTP状态吗表示请求返回结果、标记服务器处理是否正常、通知出现的错误。
三位数字和原因短语组成,第一位数字制定了响应类别,后两位无分类。不少返回的响应状态码都是错误的,但用户可能察觉不到,比如Web应用程序内部发生错误,状态吗依然返回200 OK

3.1 200 OK

表示从客户端发来的请求在服务器端被正常处理了。

3.2 204 No Content
  • 代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。

  • 一般在只需要从客户端向服务器端发送消息,而服务器端不需要向客户端发送新消息内容的情况下使用。

3.3 206 Partial Content

表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 首部字段指定范围的实体内容。

3.4 301 Moved Permanently

永久性重定向。表示请求的资源已被分配了新的 URI。以后应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。

3.5 302 Found
  • 临时性重定向。表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。

  • 和 301 Moved Permanently 状态码相似,但 302 Found 状态码代表资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的 URI 将来还有可能发生改变。

3.6 303 See Other
  • 表示由于请求的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。

  • 303 See Other 和 302 Found 状态码有着相同的功能,但 303 See Other 状态码明确表示客户端应采用 GET 方法获取资源,这点与 302 Found 状态码有区别。

3.7 304 Not Modified
  • 表示客户端发送附带条件的请求时,服务器端允许请求访问的资源,但未满足条件的情况。

  • 304 Not Modified 状态码返回时,不包含任何响应的主体部分。

  • 304 Not Modified 虽然被划分到 3xx 类别中,但和重定向没有关系。

3.8 307 Temporary Redirect

临时重定向。该状态码与 302 Found 有着相同的含义。

3.9 400 Bad Request
  • 表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。

  • 另外,浏览器会像 200 OK 一样对待该状态码。

3.10 401 Unauthorized
  • 表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。

  • 另外,若之前已进行过 1 次请求,则表示用户认证失败。

  • 返回含有 401 Unauthorized 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。

3.11 403 Forbidden

表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出详细的拒绝理由,当然也可以在响应报文的实体主体部分对原因进行描述。

3.12 404 Not Found

表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由的时候使用。

3.13 500 Internal Server Error

表明服务器端在执行请求时发生了错误。也可能是 Web 应用存在的 bug 或某些临时的故障。

3.14 503 Service Unavailable

表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入 Retry-After 首部字段再返回给客户端。

八、HTTP 报文实体

  • 报文:是网络中交换和传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变。

  • 实体:作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。


报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异

  • 内容编码:HTTP应用程序有时在发送之前需要对内容进行编码。例如,把很大的HTML文档压缩有助于减少传输实体的时间,服务器还可以把内容搅乱或加密,以此来防止未授权的第三方看到文档内容。
  • 这种类型的编码是在发送方应用到内容上,当内容经过编码后,编码好的数据就放在实体主体中,像往常一样发送给接收方。

传输编码是为了改变报文中的数据在网络上传输的方式。
分块编码是把报文分割成若干已知大小的块,块之间是紧挨着发送的,这样就不需要在发送之前知道整个报文的大小。

九、与 HTTP 协作的 Web 服务器

HTTP 通信时,除客户端和服务器外,还有一些用于协助通信的应用程序。如下列出比较重要的几个:代理、缓存、网关、隧道、Agent 代理

代理:

对于web客户端来说代理扮演的是服务器角色,接收请求报文,返回响应报文。
对于web服务器来说,代理扮演的是客户端角色,发送请求报文,接收响应报文。

缓存:

Web 缓存或代理缓存是一种特殊的 HTTP 代理服务器,可以将经过代理传输的常用文档复制保存起来。下一个请求同一文档的客户端就可以享受缓存的私有副本所提供的服务了。客户端从附近的缓存下载文档会比从远程 Web 服务器下载快得多。

HTTP / FTP 网关

网关是一种特殊的服务器,作为其他服务器的中间实体使用。通常用于将 HTTP 流量转换成其他的协议。网关接收请求时就好像自己是资源的源服务器一样。客户端可能并不知道自己正在跟一个网关进行通信。



HTTP/SSL 隧道

隧道是会在建立起来之后,就会在两条连接之间对原始数据进行盲转发的 HTTP 应用程序。HTTP 隧道通常用来在一条或多条 HTTP 连接上转发非 HTTP 数据,转发时不会窥探数据。
HTTP 隧道的一种常见用途就是通过 HTTP 连接承载加密的安全套接字层(SSL)流量,这样 SSL 流量就可以穿过只允许 Web 流量通过的防火墙了。

Agent 代理

自动搜索引擎“网络蜘蛛”

Agent 代理是代表用户发起 HTTP 请求的客户端应用程序。所有发布 Web 请求的应用程序都是 HTTP Agent 代理。




HTTPS协议:

与HTTP是两种不同的网络传输协议。
HTTP协议的信息传输完全以明文方式,不做任何加密,相当于是在网络上“裸奔”。由于传输信息是明文,这个信息有可能被某个中间人恶意截获甚至篡改。这种行为叫做中间人攻击

事先约定一种对称加密方式,并且约定一个随机生成的密钥。后续的通信中,信息发送方都使用密钥对信息加密,而信息接收方通过同样的密钥对信息解密。

这样做是不是就绝对安全了呢?并不是。

虽然我们在后续的通信中对明文进行了加密,但是第一次约定加密方式和密钥的通信仍然是明文,如果第一次通信就已经被拦截了,那么密钥就会泄露给中间人,中间人仍然可以解密后续所有的通信内容。


别担心,我们可以使用非对称加密,为密钥的传输做一层额外的保护。
非对称加密的一组秘钥对中,包含一个公钥和一个私钥。明文既可以用公钥加密,用私钥解密;也可以用私钥加密,用公钥解密。
在小灰和小红建立通信的时候,小红首先把自己的公钥Key1发给小灰:

收到小红的公钥以后,小灰自己生成一个用于对称加密的密钥Key2,并且用刚才接收的公钥Key1对Key2进行加密(这里有点绕),发送给小红:

小红利用自己非对称加密的私钥,解开了公钥Key1的加密,获得了Key2的内容。从此以后,两人就可以利用Key2进行对称加密的通信了。

在通信过程中,即使中间人在一开始就截获了公钥Key1,由于不知道私钥是什么,也无从解密。

以上的行为会被第三人继续破坏。
中间人虽然不知道小红的私钥是什么,但是在截获了小红的公钥Key1之后,却可以偷天换日,自己另外生成一对公钥私钥,把自己的公钥Key3发送给小灰。

小灰不知道公钥被偷偷换过,以为Key3就是小红的公钥。于是按照先前的流程,用Key3加密了自己生成的对称加密密钥Key2,发送给小红。

这一次通信再次被中间人截获,中间人先用自己的私钥解开了Key3的加密,获得Key2,然后再用当初小红发来的Key1重新加密,再发给小红。


这样一来,两个人后续的通信尽管用Key2做了对称加密,但是中间人已经掌握了Key2,所以可以轻松进行解密。

这时候,我们有必要引入第三方,一个权威的证书颁发机构(CA)来解决。

到底什么是证书呢?证书包含如下信息:


流程如下:

1.作为服务端的小红,首先把自己的公钥发给证书颁发机构,向证书颁发机构申请证书。

2.证书颁发机构自己也有一对公钥私钥。机构利用自己的私钥来加密Key1,并且通过服务端网址等信息生成一个证书签名,证书签名同样经过机构的私钥加密。证书制作完成后,机构把证书发送给了服务端小红。

3.当小灰向小红请求通信的时候,小红不再直接返回自己的公钥,而是把自己申请的证书返回给小灰。

4.小灰收到证书以后,要做的第一件事情是验证证书的真伪。需要说明的是,各大浏览器和操作系统已经维护了所有权威证书机构的名称和公钥。所以小灰只需要知道是哪个机构颁布的证书,就可以从本地找到对应的机构公钥,解密出证书签名。

接下来,小灰按照同样的签名规则,自己也生成一个证书签名,如果两个签名一致,说明证书是有效的。

验证成功后,小灰就可以放心地再次利用机构公钥,解密出服务端小红的公钥Key1。

5.像之前一样,小灰生成自己的对称加密密钥Key2,并且用服务端公钥Key1加密Key2,发送给小红。

6.最后,小红用自己的私钥解开加密,得到对称加密密钥Key2。于是两人开始用Key2进行对称加密的通信。

在这样的流程下,我们不妨想一想,中间人是否还具有使坏的空间呢?

如果中间人自己也向权威机构申请一个证书,并且把小红发来的证书偷偷换成自己的证书呢?
然而并没有什么卵用,因为证书的签名是由服务端网址等信息生成的,并且经过机构私钥加密,中间人也无法篡改,假证书是无法验证通过的。

HTTPS在HTTP的协议基础上增加了SSL安全层,以上一系列认证流程是在SSL层中完成的。

最新推出的TLS协议,是SSL 3.0协议的升级版,和SSL协议的大体原理是相同的。