IIS与CGI关系解读
Web服务器解析(handles)HTTP协议。
当Web服务器接收到一个HTTP请求(request),会返回一个HTTP响应 (response),例如送回一个HTML页面。
为了处理一个请求(request),Web服务器可以响应(response)一个静态页面或图片,进行页面跳转(redirect)。
为了处理一个请求(request),Web服务器可以把动态响应(dynamic response)的产生委托(delegate)给一些其它的程序。
例如:CGI脚本,JSP(JavaServer Pages)脚本,servlets,ASP(Active Server Pages)脚本,服务器端(server-side)JavaScript,或者一些其它的服务器端(server-side)技术。
编写CGI程序
下面给出两个例子(C++ C)。
1、使用C++实现的CGI输出hello world!
#include <iostream.h>
void main()
{
cout<<"Content-type:text/html\n\n"<<endl;
cout<<"Hello World!"<<endl;
}
/*
注意这里一定要按照这种格式,表示http头以供浏览器识别,
后面的\n\n是http中要求的头和后面的内容必须空一格,
而且必须使用反斜杠,不能使用" /n/n " ,这样会报错的,无法识别。
*/
2、使用C语言实现的CGI输出加粗的hello world!
#include <stdio.h>
int main()
{
printf("Content-type:text/html");
printf("\n\n");
printf("<b>Hello World!</b>");
}
上面分别是使用C++和C语言编写的hello world 例程,然后编译生成 hello.exe 可执行文件,将扩展名exe改为cgi,变为hello.cgi。
在windows xp 的IIS5.1环境配置CGI
假设我们网站根目录www下cgi目录为脚本存放目录,我们把hello.cgi文件放到cgi目录下。如下图所示:
注意:正常情况下考虑安全等因素,常将存放脚本的目录使用虚拟目录挂接,不直接放在网站根目录下!
然后我们在IIS中右击cgi目录,选择属性,打开cgi属性对话框,目录权限设置中将 读取、写入、目录访问前的勾去掉。如下图所示:
其中读取是防止在访问cgi程序时,浏览器将cgi文件作为下载文件弹出下载对话框,而不是实际执行显示在浏览器上。写入和目录访问时安全需要。这里特别注意去掉读取权限。
然后将下方的 ”执行权限“更改为 ”脚本和可执行文件“ ,这里也是重要的一步,不可以用纯脚本,一定要有可执行文件权限。
最后,点击确认再确认,重启IIS即可。
我们打开浏览器,输入 http://localhost/cgi/hello.cgi ,即可看到hello world的画面。
在win7 的IIS6.1环境配置CGI
win7中的IIS6界面和windows xp 中的IIS5.1界面发生了很大的变化,IIS 6.1中已经内置有CGI处理模块,这里直接使用即可(下面我会带领大家观察)。
新建网站cgi-test,根目录为www,下面有子目录cgi用于存放cgi脚本文件。
左侧的cgi-test网站中,我们单击cgi-test网站的cgi目录,右侧会显示cgi主页,我们在右侧 IIS 部分双击模块。
进入模块功能,可以看到CgiModule模块,我们接下来就是要使用的这个模块来实现我们的cgi功能。如下图所示:
看到这里,我们返回cgi目录的主页,双击CGI主页中的”处理程序映射“来配置 cgi文件的映射,如下图所示:
在处理程序映射界面,每一条配置的路径相当于配置的文件扩展名,状态为已启用或者禁用,处理程序即相应的模块或者脚本解释程序。
在最右侧的操作界面,我们可以看到我们可以选择的操作,其中包括 添加托管处理程序、添加脚本映射、添加通配符脚本映射,添加模块映射,和下面的编辑功能权限等。
这里我们使用的是添加模块映射和编辑功能权限。
单击添加模块映射,在出现的编译模块映射对话框中,按照上图所示配置,请求路径输入 *.cgi ,表示cgi格式文件,模块选择CgiModule,可执行文件为空,名称可以随便写,这里为cgi-exe。
确定后,增加了cgi-exe配置,然后右击这条配置选择编译功能权限,确保有执行权限,然后重启iis服务。
在浏览器中输入地址,即可查看到hello world的打印。
原理:CGI是将标准输出流重新定向到HTTP输出流来实现网页或者数据传输的。
CGI缺点:
CGI不可移植,为某一特定平台编写的CGI应用只能运行于这一环境中。每一个CGI应用存在于一个由客户端请求激活的进程中,并且在请求被服务后被卸载。这种模式将引起很高的内存、CPU开销,而且在同一进程中不能服务多个客户。