# 6.1 CGI
HTTP协议早期设计是一个通信应答协议,服务器不记录任何状态。
简单来说如下:
客户端请求服务器上的abc.html,服务器给客户端返回abc.html,完事儿结束。
想象一下客户端如果持续请求abc.html 100次,那么服务器傻傻的提供100次,因为服务器根本不记录任何状态,所以你要了,我就给就是。
这样设计的好处是足够简单,但是显然不是那么合理。
但是WWW发展,需要HTTP协议有更加强大的功能,更多需要和服务器的交互。
打个比方,登录淘宝时,每个用户进入相同的页面,但是输入了不同的用户名和密码,然后提交到服务器。
提交到服务器之后,服务器需要对用户名和密码进行验证。这种提交,显然请求的不能是简单的请求一个文件资源,而应该是调用服务器的某个方法,某个函数。
这个功能可以通过CGI来实现。
CGI是一个可执行程序,它能响应用户的请求,这个可执行程序可以使用任何语言来编写。
## 6.1 .CGI
通用网关接口(Common Gateway Interface/CGI)描述了客户端和服务器程序之间传输数据的一种标准,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI 独立于任何语言的,CGI 程序可以用任何脚本语言或者是完全独立编程语言实现,只要这个语言可以在这个系统上运行。Unix shell script, Python, Ruby, PHP, perl, Tcl, C/C++, 和 Visual Basic 都可以用来编写 CGI 程序。
最初,CGI 是在 1993 年由美国国家超级电脑应用中心(NCSA)为 NCSA HTTPd Web 服务器开发的。这个 Web 服务器使用了 UNIX shell 环境变量 来保存从 Web 服务器传递出去的参数,然后生成一个运行 CGI 的独立的进程。cgi的处理流程如下图所示:
![](https://img.kancloud.cn/68/cc/68cc694a56186704a2057910834c4dd2_1038x826.png)
* step1. web 服务器收到客户端(浏览器)的请求Http Request,启动CGI程序,并通过环境变量、标准输入传递数据
* step2. cgi进程启动解析器、加载配置(如业务相关配置)、连接其它服务器(如数据库服务器)、逻辑处理等
* step3. cgi程将处理结果通过标准输出、标准错误,传递给web 服务器
* step4. web 服务器收到cgi返回的结果,构建Http Response返回给客户端,并杀死cgi进程
web服务器与cgi通过环境变量、标准输入、标准输出、标准错误互相传递数据。
>在遇到用户连接请求:
>1 先要创建cgi子进程,然后cgi子进程处理请求。处理完事退出这个子进程:fork-and-execute
>2 cgi方式是客户端有多少个请求,就开辟多少个子进程,每个子进程都需要启动自己的解释器,加载配置,连接其他服务器等初始化工作,这是cgi进程性能低下的主要原因。当用户请求非常多的时候,会大量的占用内存、cpu等资源。造成性能低下。
### 环境变量
GET请求,它将数据打包放置在环境变量QUERY_STRING中,CGI从环境变量QUERY_STRING中获取数据。常见的环境变量如下表所示:
| 环境变数 | 内容 |
| -- | -- |
| AUTH_TYPE |存取认证类型。|
| CONTENT_LENGTH | 由标准输入传递给CGI程序的数据长度,以bytes或字元数来计算。 |
| CONTENT_TYPE | 请求的MIME类型|
| GATEWAY_INTERFACE | 服务器的CGI版本编号。 |
| HTTP_ACCEPT |浏览器能直接接收的Content-types, 可以有HTTP Accept header定义. |
| HTTP_USER_AGENT |递交表单的浏览器的名称、版本 和其他平台性的附加信息。 |
| HTTP_REFERER| 递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它 |
| PATH_INFO | 传递给cgi程式的路径信息|
| QUERY_STRING |传递给CGI程式的请求参数,也就是用"?"隔开,添加在URL后面的字串。|
| REMOTE_ADDR | client端的host名称 |
| REMOTE_HOST | client端的IP位址。 |
| REMOTE_USER |client端送出来的使用者名称。 |
| REMOTE_METHOD | client端发出请求的方法(如get、post)。 |
| SCRIPT_NAME | CGI程式所在的虚拟路径,如/cgi-bin/echo。 |
| SERVER_NAME | server的host名称或IP地址。 |
| SERVER_PORT| 收到request的server端口。 |
| SERVER_PROTOCOL |所使用的通讯协定和版本编号。 |
| SERVER_SOFTWARE | server程序的名称和版本。|
## 标准输入
环境变量的大小是有一定的限制的,当需要传送的数据量大时,储存环境变量的空间可能会不足,造成数据接收不完全,甚至无法执行CGI程序。因此后来又发展出另外一种方法:POST,也就是利用I/O重新导向的技巧,让CGI程序可以由STDIN和STDOUT直接跟浏览器沟通。
当我们指定用这种方法传递请求的数据时,web 服务器收到数据后会先放在一块输入缓冲区中,并且将数据的大小记录在CONTENT_LENGTH这个环境变数,然后调用CGI程式并将CGI程序的STDIN指向这块缓冲区,于是我们就可以很顺利的通过STDIN和环境变数CONTENT_LENGTH得到所有的资料,再没有资料大小的限制了。
总结:CGI使外部程序与Web服务器之间交互成为可能。CGI程式运行在独立的进程中,并对每个Web请求建立一个进程,这种方法非常容易实现,但效率很差,难以扩展。面对大量请求,进程的大量建立和消亡使操作系统性能大大下降。此外,由于地址空间无法共享,也限制了资源重用。
- 概要
- 1 分布式存储fastDFS
- 1.1 fastDFS 通用介绍
- 1.2 fastDFS安装和使用
- 1.3 基于fastDFS实现分布式
- 2 缓存数据库redis快速搭建
- 2.1 环境安装
- 2.2 redis数据类型
- 2.3 redis订阅发布模式
- 2.4 redis事务
- 2.5 redis备份
- 3 redis详细攻略
- 3.1 redis简介
- 3.2 redis使用场景
- 3.3 redis基本操作
- 3.4 redis数据类型
- 3.4.1 字符串
- 3.4.2 HASH-字典
- 3.4.3 List-列表
- 3.4.4 Set-集合
- 3.4.5 Sorted Set-有序集合
- 3.4.6 订阅-发布
- 3.4.7 事务
- 3.5 redis配置文件
- 3.6 持久化
- 3.7 redis性能测试
- 3.8 redis-C-API
- 3.9 redis-C++-API
- 3.10 总结与建议
- 4 memcache缓存数据库
- 4.1 什么是memcached
- 4.2 memcached的特征
- 4.3 memcached的内存管理
- 4.4 如何使用memcached
- 4.5 memcached参数详解
- 4.6 memcached安装
- 4.7 memcached-C客户端
- 4.8 memcached-C++客户端
- 5 Nginx
- 6 FastCGI
- 6.1 CGI
- 6.2 FastCGI
- 6.3 Nginx与FastCGI
- 7 Nginx上部署fastDFS
- 8 项目概要
- 8.1 上传文件功能
- 8.2 主界面显示与下载文件功能
- 8.3 注册功能
- 8.4 登陆功能
- 8.5 文件分类功能
- 8.6 个人网盘功能
- 8.8 秒传功能