作者:你走以后_心若逝世灰决_677 | 来源:互联网 | 2023-10-15 08:25
图6.7展示了服务器程序的工作过程,这个过程不仅限于Web服务器,对于各种服务器程序都是共通的,收发数据的过程也是大同小异的。各种服务器程序的不同点在于图中(b)客户端通信部分的第一行调用read后面的如下部分。
[处理请求消息内容];
图6.7中只写了一行,但实际上这里应该是一组处理各种工作的程序,或者说这里才是服务器程序的核心部分。接下来让我们来对这一部分进行探索。
Web服务器中,图6.7的read获取的数据内容就是HTTP请求消息服务器程序会根据收到的请求消息中的内容进行相应的处理,并生成响应消息,再通过write返回给客户端。请求消息包括一个称为“方法”的命令,以及表示数据源的URI(文件路径名),服务器程序会根据这些内容向客户端返回数据,但对于不同的方法和URI,服务器内部的工作过程会有所不同。下面我们从简单的开始依次进行介绍。
最简单的一种情况如图6.8中的例子所示,请求方法为GET, URI为一个HTML文件名。这种情况只要从文件中读出HTML文档,然后将其作为响应消息返回就可以了。不过,按照URI从磁盘上读取文件并没有这么简单。如果完全按照URI中的路径和文件名读取,那就意味着磁盘上所有的文件都可以访问,Web服务器的磁盘内容就全部暴露了,这很危险。因此,这里需要一些特殊的机制。
Web服务器公开的目录其实并不是磁盘上的实际目录,而是如图6.9这样的虚拟目录,而URI中写的就是在这个虚拟目录结构下的路径名。因此,当读取文件时,需要先查询虚拟目录与实际目录的对应关系,并将URI转换成实际的文件名后,才能读取文件并返回数据。举个例子,假设我们的虚拟目录结构如图6.9所示,如果请求消息中的URI如下页(1)所示,那么因为/~user2/…对应的实际目录为/home/user2/…,所以将URI转换成实际文件名后应该是如下页(2)。
客户端看到的Web服务器目录是虚拟的,和实际的目录结构不同。Web服务器内部会将实际的目录名和供外部访问的虚拟目录名进行关联。
于是,服务器就会根据上述路径从磁盘中读取相应的文件,然后将数据返回给客户端。
文件名转换是有特例的,比如URI中的路径省略了文件名的情况,这时服务器会读取事先设置好的默认文件名。例如在浏览器中输入如下网址。
上面这个网址省略了文件名,服务器会在末尾添加默认文件名,如下。
在这个例子中,index.html这个文件名是在服务器中设置好的,服务器会将它添加在目录名的后面。
有些Web服务器程序还具有文件名改写功能,只要设置好改写的规则,当URI中的路径符合改写规则时,就可以将URI中的文件名改写成其他的文件名进行访问。当出于某些原因Web服务器的目录和文件名发生变化,但又希望用户通过原来的网址进行访问的时候,这个功能非常有用。
运行CGI程序
如果URI指定的文件内容为HTML文档或图片,那么只要直接将文件内容作为响应消息返回客户端就可以了。但URI指定的文件内容不仅限于HTML文档,也有可能是一个程序。在这个情况下,服务器不会直接返回文件内容,而是会运行这个程序,然后将程序输出的数据返回给客户端。Web服务器可以启动的程序有几种类型,每种类型的具体工作方式有所区别,下面我们来看看CGI程序是如何工作的。
Web服务器运行程序时,一般来说浏览器会将需要程序处理的数据放在HTTP请求消息中发送给服务器。
这些数据有很多种类,例如购物网站订单表中的品名、数量、发货地址等,搜索引擎中输入的关键字也是一个常见的例子。
总之,浏览器需要在发送给Web服务器的请求消息中加入一些数据。
有两种加入数据的方法。
get
post
收到请求消息之后,Web服务器会进行下面的工作。
首先,Web服务器会检查URI指定的文件名,看一看这个文件是不是一个程序。
这里的判断方法是在Web服务器中事先设置好的,一般是通过文件的扩展名来进行判断
,例如将.cgi、.php等扩展名的文件设置为程序,当遇到这些文件时,Web服务器就会将它们作为程序来对待。
也可以设置一个存放程序的目录,将这个目录下的所有文件都作为程序来对待。此外,还可以根据文件的属性来进行判断。
如果判断要访问的文件为程序文件,Web服务器会委托操作系统运行这个程序,然后从请求消息中取出数据并交给运行的程序。
如果方法为GET,则将URI后面的参数传递给程序;
如果方法为POST,则将消息体中的数据传递给程序(图6.11)。
Web服务器程序在组装网络包、还原数据之后,会运行其中指定的程序(实际是委托操作系统来运行),然后将数据传递给已运行的程序。接下来,运行的程序收到数据后会进行一系列处理,并将输出的数据返回给Web服务器。程序可以返回各种内容,如表示订单已接受的说明,或者按照关键字从数据库中搜索出的结果等。
无论如何,为了将数据处理的结果返回给客户端,首先需要将它返回给Web服务器。这些输出的数据一般来说会嵌入到HTML文档中,因此Web服务器可以直接将其作为响应消息返回给客户端。输出数据的内容是由运行的程序生成的,Web服务器并不过问,也不会去改变程序输出的内容。
返回响应消息
当服务器完成对请求消息的各种处理之后,就可以返回响应消息了。这里的工作过程和客户端向服务器发送请求消息时的过程相同。
1 Web服务器调用Socket库的write,将响应消息交给协议栈。
这时,需要告诉协议栈这个响应消息应该发给谁,但我们并不需要直接告知客户端的IP地址等信息,而是只需要给出表示通信使用的套接字的描述符就可以了。
2 协议栈会将数据拆分成多个网络包,然后加上头部发送出去。这些包中包含接收方客户端的地址,它们将经过交换机和路由器的转发,通过互联网最终到达客户端。
总结
- 依据请求的不同,有些可能是简单的网页,有些可能需要运行程序
参考
CGI介绍_liitdar的博客-CSDN博客_cgi csdn