HTTP协议(四):Web服务器的工作流程

2019-12-01 14:37  |  分类:理论知识  |  标签: HTTP原理分析书籍浏览器解析

摘要:上一篇文章我们细致讲了HTTP的连接管理的相关内容。这一篇文章讲下Web服务器的工作流程。

Web服务器的简易工作流程

大多数web服务器都会执行相同几项任务:

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

第一步:接收客户端连接

如果服务器已经接收了一条客户端的连接接,那么就可以使用这条连接来对客户端发送响应,或者客户端利用这条连接发送请求。

处理新连接

客户端对服务器进行请求时,会与Web服务器建立一条TCP连接,此时服务器会对客户端进行判断,从TCP连接中将IP地址解析出来。一旦该连接被服务器所接受,那么服务器就会将这条连接加入到连接列表中,做好数据传输的准备。

客户端主机名识别

使用“反向DNS”对大部分服务器进行配置,以便将客户端IP地址转成客户端主机名。但要注意,主机名的查找可能耗费大量时间,这样一来就会导致web服务器处理事务的效率大大降低。因此一般来说,服务器要么会禁止主机名解析,或者只允许对特定的内容进行解析。

通过ident确定客户端用户

有些服务器还支持IETF的ident协议,服务器可以通过ident协议找到发起HTTP连接的用户名。如果客户端支持ident协议,就在TCP端口113上监听ident请求。ident协议工作流程简单的来说:客户端打开一条HTTP连接,然后服务器打开自己到客户端ident服务端口(113),发送一条简单的请求,询问与新连接相对应的用户名,并从客户端解析出包含用户名的响应。

虽然ident能很好的工作,但是在公网上却存在问题:

  • 很多客户端PC没有运行ident识别协议的守护进程。
  • ident协议会使HTTP事务处理产生严重的时延。
  • 很多防火墙不允许ident流量进入
  • ident协议不安全,容易被伪造。
  • ident协议也不支持虚拟IP地址
  • 暴露客户端用户名涉及到安全隐私问题。

第二步:接收请求报文

连接上有数据到达时,服务器会从网络连接中读取数据,并将其解析出来。

  • 解析请求行,查找请求方法,指定的资源识别符(URI)以及版本号,各项之间由一个空格分隔,并以一个回车换行(CRLF)序列作为行的结束。
  • 读取以CRLF结尾的报文首部
  • 检测到以CRLF结尾的、标识首部结束的空行。(如果有的话)
  • 如果有的话(长度由Content-Length)。读取请求主体。

第三步:处理请求

一旦服务器接收到请求,就可以根据方法、资源、首部和可选的主体部分来对请求进行处理了。

方法名称 描述
GET 请求服务器发送某个资源
POST 向服务器发送数据
PUT 向服务器写入文档
DELETE 请求服务器删除文档
TRACE 在请求的过程中,会经过网关,代理,防火墙等,这些都可以更改请求。因此使用此方法可以返回请求在最终发送给服务器时,变成什么样子。
HEAD 与GET方法类似,不同在于,这里仅返回首部,不返回实体内容
OPTIONS 告知客户方服务器支持的各种功能

第四步:对资源的映射及访问

Web服务器是资源服务器,负责发送预先创建好的内容,比如HTML页面,图片,以及运行在服务器上的资源生成程序锁产生的动态内容。在服务器将内容传送给客户端之前,要讲请求报文中的URI映射为Web服务器上适当的内容或内容生成器,以识别出内容的源头。

docroot

Web服务器支持各种不同类型的资源映射,但最简单的资源映射就是用请求URI作为名字来访问Web服务器文件系统的文件。通常,Web服务器的文件系统会有一个特殊的文件夹专门用于存放web内容。这个文件夹被称为文档的根目录(docroot 或 document root)。Web服务器从请求报文中获取URI,并将其附加到文档根目录的后面。

目录列表

Web服务器可以接收到对目录URL的请求,其路径可以解析为一个目录,而不是文件。我们可以对大多数Web服务器进行配置,使得客户端访问目录URL时采取不同的动作:返回一个错误、或一个目录索引列表等

动态内容资源的映射

Web服务器还可以将URI映射为动态资源——既是内容是由生成程序生成的,而非是某个具体的静态文件。Web服务器要可以识别出资源什么时候是动态,动态内容生成程序位于何处,如何运行该程序。

服务器端包含项

很多Web服务器对服务器端包含项SSI的支持。如果某个资源被标识为存在服务器端包含项,服务器就会在将其发送给客户端之前对资源内容进行处理。要对内容进行扫描,以查找特定模板(如:SHTML的Includes语法),这些模板可以是变量名,也可以是嵌入式脚本。这是创建动态内容一种简单方式。

访问控制

web服务器可以对特定资源进行访问控制。有请求到达且需要访问受控资源时,Web服务器可以根据需要来对访问进行权限控制,如:要求输入账号密码。

第五步:构建响应

如果事务处理产生了响应主题,就将内容放到响应报文发送回去,如果有响应主体的话,响应报文通常包括:

  • 描述响应主体MIME类型的Content-Type首部。
  • 描述了响应主体长度的Content-Length首部;
  • 实际报文的主体内容

MIME类型

Web服务器要负责确定响应主体的MIME类型。

  • MIME类型(mime.types)

    Web服务器可以用文件的扩展名来说明MIME类型,Web服务器会为每个资源扫描一个包含所有扩展名的MIME类型的文件,已确定其MIME类型。

  • 魔法分类

    一些Web服务器可以扫描每一个资源的内容,并将其与一个已知模式表(称之为魔法文件)进行匹配,以决定每个文件的MIME类型。这种做法很适合用于一些没有扩展名的文件。

  • 显示分类

    可以对Web服务器进行配置,使其不考虑文件的扩展名或内容,强制特定文件或目录内容拥有某个MIME类型

  • 类型协商

    有些WEB服务器经过配置,可以以多种文档格式来存储资源。在这种情况下,可以配置Web服务器,使其可以通过与用户协商来决定使用哪种格式以及相关的MIME类型。

重定向

Web服务器有时会返回重定向响应而不是成功的报文,Web服务器可以将浏览器重定向到其他地方来执行请求。重定向状态码用户3XX说明。Location首部包含了内容的新地址或优选地址的URI。

  • 永久搬离的资源

    资源可能已经被移动到了新的位置,或者被重新命名,有了一个新的URI。通过重定向可以告诉客户端资源已经被重命名或永久搬离了。状态码301 Moved Permanently就用于此类重定向。

  • 临时搬离的资源

    资源只是临时性的被移动走或重命名,服务器希望将客户端重定向到新的位置上去,但是由于是临时性质的,所以服务器希望客户端将来还可以回头去使用老的URI。状态码303 See Other以及状态码307 Temporary Redirect就用于此类重定向

  • URI增强

    服务器通常用于重定向来重写URL,往往用于嵌入上下文。当请求到达时,服务器会生成一个新的包含了嵌入式状态新的URL,并将用户重定向到这个新的URL上去。客户端会跟随这个重定向信息,重新发起请求。但这次请求会包含完整的,经过状态增强的URL。这是事务间维护状态的一种有效方式。状态码303 See Other以及状态码307 Temporary Redirect就用于此类重定向

  • 负载均衡

    如果有一个超载的服务器接收到一条请求,服务器可以将客户端重定向一个负载不太重的服务器上去。状态码303 See Other以及状态码307 Temporary Redirect就用于此类重定向。

  • 服务器关联

    Web服务器上可能会有某些用户的本地信息,服务器可以将客户端重定向到包含了那个客户端信息的服务器上去。状态码303 See Other以及状态码307 Temporary Redirect就用于此类重定向。

  • 规范目录名称

    客户端请求的URI是一个不带尾部斜杆的目录名时,大多数Web服务器都会将客户端重定向到一个加了斜杆的URI上。

第六步:发送响应

Web服务器通过连接发送数据时会面临与接收数据一样问题。服务器可能有多条到客户端的连接。有些是空闲的,有些在向服务器发送数据,还有一些向客户端回送响应数据。服务器要记录连接的状态,还要特别注意对持久连接的处理;对非持久连接而言,服务器应该在发送了整条报文之后,关闭自己这一端的连接。对持久连接来说,连接可能仍保持打开状态,在这种情况下,服务器要特别小心要正确地计算Content-Length首部,不然客户端就无法知道响应什么时候结束了。

第七部:记录日志

最后当事务结束时,web服务器会在日志文件添加一个条目,来描述已执行的事务。

致谢

HTTP权威指南