网络基础——HTTP协议

230 阅读15分钟

       当我们在网页浏览器(Web browser)的地址栏中输入URL 时,Web 浏览器地址栏根据指定的URL,Web 浏览器从Web 服务器端获取文件资源(resource)等信息,从而显示出 Web 页面。

      Web 使用 HTTP(HyperText Transfer Protocol,超文本传输协议 )的协议作为规范,完成从客户端到服务器端等一系列运作流程。 

简单的 HTTP 协议

        HTTP 协议和TCP/IP 协议族内的其他众多的协议相同,用于客户端和服务器之间的通信。 请求资源的一端称为客户端,而提供资源响应的一端称为服务器端。

        HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。当用户在浏览器的地址栏里输入所要访问Web页的URI以后,HTTP的处理即会开始。步骤如下:

  1. 浏览器从URL中解析出服务器的域名;
  2. 浏览器通过DNS服务器把域名转换成服务器的IP地址;
  3. 浏览器建立一条与Web服务器的TCP连接;
  4. 浏览器向服务器发送一条HTTP请求报文;
  5. 服务器向浏览器回送一条HTTP响应报文;
  6. 关闭连接,浏览器显示文档。

无状态(stateless)协议

       HTTP 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自 身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个 级别,协议对于发送过的请求或响应都不做持久化处理。

       使用 HTTP 协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。

Cookie

Cookie会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。 服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一 个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

URI 和 URL

       URL(Uniform Resource Locator,统一资源定位符)。URL 正是使用 Web 浏览器等 访问 Web 页面时需要输入的网页地址。URI(统一资源标识符)就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。URI 用字符串标识某一互联网资源,而URL表示资源的地点(互联 网上所处的位置)。可见 URL是URI 的子集。

URI 格式

HTTP 方法

  • GET

GET是最常用的方法。通常用于请求服务器发送某个资源。

  • HEAD

HEAD方法与GET方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。

  • PUT

与GET从服务器读取文档相反,PUT方法会向服务器写入文档。PUT方法的语义就是让服务器用请求的主体部分来创建一个由所请求的URL命名的新文档,或者,如果那个URL已经存在的话,就用这个主体来替代它。

  • POST

POST方法起初是用来向服务器输入数据的。实际上,通常会用它来支持HTML的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方

  • TRACE

客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP请求。TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。TRACE方法主要用于诊断;用于验证请求是否如愿穿过了请求/响应链。

  • OPTIONS

OPTIONS方法请求Web服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。

  • DELETE

与 PUT 相反的方法。DELETE 方法按请求 URI删除指定的资源。

HTTP 状态码

         每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。

       状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。

HTTP状态码被分成了五大类

  • 100~199——信息性状态码:接收的请求正在处理

  • 200~299——成功状态码: 请求正常处理完毕

  • 300~399——重定向状态码:需要进行附加操作以完成请求

  • 400~499——客户端错误状态码:服务器无法处理请求

  • 500~599——服务器错误状态码:服务器处理请求出错

204 No Content

       代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如, 当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面不发生更新。 一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。

206 Partial Content

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

301 Moved Permanently

       永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后 应使用资源现在所指的 URI。

302 Found

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

400 Bad Request

       该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求 的内容后再次发送请求。

404 Not Found

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

500 Internal Server Error

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

HTTP 报文

        HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。 HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。 HTTP 报文大致可分为报文首部和报文主体两块。

HTTP 首部

HTTP首部字段根据实际用途被分为以下4 种类型:

  • 通用首部字段(General Header Fields)请求报文和响应报文两方都会使用的首部。
  • 请求首部字段(Request Header Fields)从客户端向服务器端发送请求报文时使用的首部。
  • 响应首部字段(Response Header Fields)从服务器端响应报文时使用的首部。
  • 实体首部字段(Entity Header Fields)针对请求报文和响应报文的实体部分使用的首部。

连接管理

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

        客户端发送HTTP 请求。 接着,为了传输方便,在传输层(TCP 协议)把从应用层处收到的数据(HTTP 请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。 在网络层(IP 协议),增加作为通信目的地的 MAC 地址后转发给链路层。 接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP 请求。

TCP套接字

       在任意时刻计算机都可以有几条TCP连接处于打开状态。TCP是通过端口号来保持所有这些连接的正确运行的。操作系统提供了一些操纵其TCP连接的工具。这个套接字API向HTTP程序员隐藏了TCP和IP的所有细节。

套接字API允许用户创建TCP的端点数据结构,将这些端点与远程服务器的TCP端点进行连接,并对数据流进行读写。TCP  API隐藏了所有底层网络协议的握手细节,以及TCP数据流与IP分组之间的分段和重装细节。

         我们从Web服务器等待连接S4开始。客户端根据URL判定出IP地址和端口号,并建立一条到服务器的TCP连接C3。建立连接可能要花费一些时间,时间长短取决于服务器距离的远近、服务器的负载情况,以及因特网的拥挤程度。 一旦建立了连接,客户端就会发送HTTP请求C5,服务器则会读取请求S6。一旦服务器获取了整条请求报文,就会对请求进行处理,执行所请求的动作S7,并将数据写回客户端。客户端读取数据C6,并对响应数据进行处理C7。

持久连接

       HTTP中常用的有两个版本,一个HTTP1.0,另一个是HTTP1.1。在HTTP1.0中每一个命令和应答都会触发一次TCP连接的建立和断开。而从HTTP1.1开始,支持持久连接(HTTP keep-alive )的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。大量地减少了TCP连接的建立和断开操作,从而也提高了效率。在 HTTP/1.1 中,所有的连接默认都是持久连接。除了服务器端,客户端也需要支持持久连接。

Web服务器的实现

         Web 服务器实现了HTTP和相关的TCP连接处理。负责管理Web服务器提供的资源,以及对Web服务器的配置、控制及扩展方面的管理。 

        Web服务器逻辑实现了HTTP协议、管理着Web资源,并负责提供Web服务器的管理功能。Web服务器逻辑和操作系统共同负责管理TCP连接。底层操作系统负责管理底层计算机系统的硬件细节,并提供了TCP/IP网络支持、负责装载 Web资源的文件系统以及控制当前计算活动的进程管理功能。

基本Web 服务器请求的步骤

  1. 建立连接——接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭。
  2. 接收请求——从网络中读取一条HTTP请求报文。 
  3. 处理请求——对请求报文进行解释,并采取行动。 
  4. 访问资源——访问报文中指定的资源。 
  5. 构建响应——创建带有正确首部的HTTP响应报文。 
  6. 发送响应——将响应回送给客户端。
  7. 记录事务处理过程——将与已完成事务有关的内容记录在一个日志文件中。

web服务器类型

  • 单线程Web服务器

单线程的Web服务器一次只处理一个请求,直到其完成为止。一个事务处理结束之后,才去处理下一条连接。这种结构易于实现,但在处理过程中,所有其他连接都会被忽略。这样会造成严重的性能问题,只适用于低负荷的服务器,以及type-o-serve 这样的诊断工具。

  • 多进程及多线程Web服务器

多进程和多线程Web服务器用多个进程,或更高效的线程同时对请求进行处理。可以根据需要创建,或者预先创建一些线程/进程。有些服务器会为每条连接分配一个线程/进程,但当服务器同时要处理成百、上千,甚至数以万计的连接时,需要的进程或线程数量可能会消耗太多的内存或系统资源。因此,很多多线程Web服务器都会对线程/进程的最大数量进行限制。 

  • 复用I/O的服务器

      为了支持大量的连接,很多Web服务器都采用了复用结构。在复用结构中,要同时监视所有连接上的活动。当连接的状态发生变化时(比如,有数据可用,或出现错误时),就对那条连接进行少量的处理;处理结束之后,将连接返回到开放连接列表中,等待下一次状态变化。只有在有事情可做时才会对连接进行处理;在空闲连接上等待的时候并不会绑定线程和进程。

  • 复用的多线程Web服务器

        有些系统会将多线程和复用功能结合在一起,以利用计算机平台上的多个CPU。 多个线程(通常是一个物理处理器)中的每一个都在观察打开的连接(或打开的连接中的一个子集),并对每条连接执行少量的任务。

HTTPS

HTTP 的缺点

HTTP 的缺点如下:

  • 通信使用明文,内容可能会被窃听

由于 HTTP 本身不具备加密的功能,所以也无法做到对通信整体(使用 HTTP 协议通信的请求和响应的内容)进行加密。即,HTTP 报文使用明文方式发送。

  • 不验证通信方的身份,因此有可能遭遇伪装

HTTP 协议中的请求和响应不会对通信方进行确认。也就是说任何人都可发起请求。

  • 无法证明报文的完整性,所以有可能已遭篡改

所谓完整性是指信息的准确度。接收到的内容可能有误已遭篡改。

建立安全传输

       HTTP+ 加密 + 认证 + 完整性保护 =HTTPS,HTTP 加上加密处理和认证以及完整性保护后即是 HTTPS

      HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。 通常,HTTP 直接和 TCP 通信。当使用 SSL 时,则演变成先和 SSL 通 信,再由 SSL 和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP。

         在未加密HTTP中,客户端会打开一条到Web服务器端口80的TCP连接,发送一条请求报文,接收一条响应报文,关闭连接。由于SSL安全层的存在,HTTPS中这个过程会略微复杂一些。在HTTPS中,客户端首先打开一条到Web服务器端口443(安全HTTP的默认端口)的连接。一旦建立了TCP连接,客户端和服务器就会初始化SSL层,对加密参数进行沟通,并交换密钥。握手完成之后,SSL初始化就完成了,客户端就可以将请求报文发送给安全层了。在将这些报文发送给TCP之前,要先对其进行加密。

SSL握手

        SSL是个复杂的二进制协议,在发送已加密的HTTP报文之前,客户端和服务器要进行一次SSL握手,在这个握手过程中,它们要完成以下工作: 

  • 交换协议版本号;
  • 选择一个两端都了解的密码;
  • 对两端的身份进行认证;
  • 生成临时的会话密钥,以便加密信道。

服务器证书

       服务器证书是一个显示了组织的名称、地址、服务器DNS域名以及其他信息的X.509v3派生证书。你和你所用的客户端软件可以检查证书,以确保所有的信息都是可信的。 SSL支持双向认证,将服务器证书承载回客户端,再将客户端的证书回送给服务器。

参考

图解HTTP
HTTP权威指南