Common Gateway Interface:
CGI: 在物理上是一段程序,运行在服务器上,提供同客户端 Html页面的接口。规定了Web服务器调用其他可执行程序(CGI程序)的接口协议标准,以此实现服务器(server)和浏览器(web browser)的交互。CGI程序一般完成Web网页中表单(Form)数据的处理、数据库查询和与传统应用程序的集成等。
CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。CGI接口标准包括标准输入、环境变量、标准输出三部分。
标准输入:
CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。
GET方法与POST方法:HTTP 定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST。事实上 GET 适用于多数请求,而保留 POST 仅用于更新站点。理论上说,GET是从服务器上请求数据,POST是发送数据到服务器。
传递参数方式:如果以GET方式传输,所带参数附加在CGI程式的URL后直接传给server,并可从server端的QUERY_STRING这个环境变量中读取;如果以POST方式传输,则参数会被打包在数据报中传送给server,并可从CONTENT_LENGTH这个环境变量中读取出来。
还有一种情况是,你用的是GET方式,但传送的参数是路径,如: <a href="/cgi-bin/a.pl/usr/local/bin/pine" > CGI < /a> 这时所传递的参数"/usr/local/bin/pine"存放在PATH_INFO这个环境变量中。环境变量的读取方式为 $str=$ENV{'QUERY_STRING'};
Get 方法需要使用 Request.QueryString 来取得变量的值;而 Post 方式通过 Request.Form 来访问提交的内容。
Get 方式传输的数据量非常小,一般限制在 2 KB 左右,但是执行效率却比 Post 方法好;而 Post 方式传递的数据量相对较大,它是等待服务器来读取数据,不过也有字节限制,这是为了避免对服务器用大量数据进行恶意攻击。除非你肯定你提交的数据可以一次性提交,否则请尽量用 Post 方法。
Get 方式提交数据,会带来安全问题,比如一个登陆页面,通过 Get 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问客户这台机器,就可以从历史记录获得该用户的帐号和密码,所以表单提交建议使用 Post 方法;Post 方法提交的表单页面常见的问题是,该页面如果刷新的时候,会弹出一个对话框。
标准输出:
CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者Html文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出。
环境变量:
SERVER-NAME:运行CGI序为机器名或IP地址。 SERVER-INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。 SERVER-PROTOCOL:通信协议,应当是HTTP/1.0。 SERVER-PORT:TCP端口,一般说来web端口是80。 HTTP-ACCEPT:HTTP定义的浏览器能够接受的数据类型。 HTTP-REFERER:发送表单的文件URL。(并非所有的浏览器都传送这一变量) HTTP-USER-AGENT:发送表单的浏览器的有关信息。 GETWAY-INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。 PATH-TRANSLATED: PATH-INFO中包含的实际路径名。 PATH-INFO:浏览器用GET方式发送数据时的附加路径。 SCRIPT-NAME: CGI程序的路径名。 QUERY-STRING:表单输入的数据,URL中间号后的内容。 REMOTE-HOST:发送程序的主机名,不能确定该值。 REMOTE-ADDR:发送程序的机器的IP地址。 REMOTE-USER:发送程序的人名。 CONTENT-TYPE:POST发送,一般为applioation/xwww-form-urlencoded。 CONTENT-LENGTH:POST方法输入的数据的字节数。
CGI程序格式:
echo "Content-type: text/html" ; echo "" 或者 printf (″Content type: text/plain\n\n″); 的前缀必须加上。通过标准输出将字符串″Content type :text/plain\n\n″传送给Web服务器。它是一个MIME头信息,它告诉Web服务器随后的输出是以纯ASCII文本的形式。请注意在这个头信息中有两个新行符,这是因为Web服务器需要在实际的文本信息开始之前先看见一个空行。
下边举例:
通过 xmlhttp.open("GET","/cgi-bin/test_cli.sh?c=" + document.getElementById("ID_INPUT_CLI").value, true); 给test_cli.sh 这个shell脚本的CGI程序传递的参数为 ID_INPUT_CLI 的 value。在test_cli.sh中:cmd=${QUERY_STRING/*=/} 首先QUERY_STRING即为GET方式传递的url值(包含参数),然后截取 = 之后的值,即为实际需要的命令。接下来,就可以尽情发挥shell脚本的作用了。
CGI的配置:
在Apache的httpd.conf中只需执行CGI目录,添加相应的Options即可。 如
/cgi-bin/ "/opt/GUI/cgi-bin/"
...
Options +ExecCGI
...
CGI程序仅限root执行权限:在源代码编译Apache时,添加 CFLAGS = -DBIG_SECURITY_HOLE ./configure --prefix=/opt/http_server&& make && make install.
或者,在Include/http_config.h中添加:
#ifndef BIG_SECURITY_HOLE
#define BIG_SECURITY_HOLE
#endif
。