cgi和fastcgi获取所有环境变量(C语言)

参考:http://blog.chinaunix.net/uid-620765-id-2084386.html

还记得C语言main函数的完整声明吗?

   int main(int argc, char **argv, char **envp);
  
   这个就是c语言中main函数的完整声明, argc表示参数个数,argv表示参数字符串,而这个envp就表示环境变量字符串。参数和环境变量都可以不止一个,所以,用指向字符串指针的指针来表示。

  比如我们用C语言写了一个程序,运行在命令行下,带有2个参数

  C:> cpfile.exe c:\test.txt d:\test.txt

  那么这里的
  argc=3;
  argv[0] = "cpfile.exe";
  argv[1] = "c:\test.txt";
  argv[2] = "d:\test.txt";

  在c语言中的stdlib.h中有一个
  extern char **environ; 或者
  extern char **_environ;的声明
  这个envp的参数实际上就是environ。

  好,我们看看在cgi程序(其实就是一个C语言程序)里面怎么枚举这些环境变量

  先写一个html页面:(当然也可以不要)   

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
<title>test</title>
<script type="text/javascript">
function post_submit()
{
	document.getElementById( "mainform" ).method = "post";
	document.getElementById( "mainform" ).submit();
}

function get_submit()
{
	document.getElementById( "mainform" ).method = "get";
	document.getElementById( "mainform" ).submit();
}
</script>
</head>
<body>
<div class="editView">
<form id="mainform" method="post" action="/printenv.cgi" enctype="multipart/form-data">
	<fieldset class="">
		<legend>测试页面</legend>
		<dl class="nowrap">
			<dd>
				<span>名称</span>:
				<input id="name" name="name" type="text" value="ldapserver_name">
				<span>IP</span>:
				<input id="ip" name="ip" type="text">
			</dd>
		</dl>
		<dl class="nowrap">
			<dd>
				<span>复选框1</span>:
				<input id="checkbox1" name="checkbox1" type="checkbox" checked/>
				<span>    复选框1</span>:
				<input id="checkbox2" name="checkbox2" type="checkbox" />
			</dd>
		</dl>
		<dl class="nowrap">
			<dd>
				<label for="radiotest1">单选按钮1</label>
				<input name="radiotest" id="radiotest1" type="radio" value="1"/>
				<label for="radiotest2">  单选按钮2</label>
				<input name="radiotest" id="radiotest2" type="radio" value="2" checked/>
				<label for="radiotest3">  单选按钮3</label>
				<input name="radiotest" id="radiotest3" type="radio" value="3"/>
			</dd>
		</dl>
		<dl class="nowrap" id="dl_ca">
			<dd>
				<span>上传文件</span>
				<input class="" name="uploadfile" id="uploadfile" type="file"/>
			</dd>
		</dl>
		<dl class="nowrap">
			<dd><span>下拉框</span>:
				<select name="dropbox" id="dropbox">
					<option value="3">3</option>
					<option value="2">2</option>
				</select>
			</dd>
		</dl>
	</fieldset>
	<fieldset class="btnfield">
		<dl class="nowrap">
			<dt> </dt>
			<dd>
				<a id="submit" href="javascript:;" value="Submit" οnclick="javascript: post_submit();">post提交</a>
				  <a id="submit" href="javascript:;" value="Submit" οnclick="javascript: get_submit();">get提交</a>
				  <a href="javascript:;">取消</a>
			</dd>
		</dl>
	</fieldset>
</form>
</div>
</body>
</html>


呈现效果如下:


cgi程序源码:

/* env.c */
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
  
int main()  
{  
    extern char   **environ;  
    int nlen = 0;  
    int i;  
    char *psz_content = NULL;  
    char **pp_env;   

    printf("Content-type: text/html\n\n");  
     
    for ( pp_env = environ; *pp_env; pp_env++ )  
        printf("%s<br>", *pp_env);  
  
    if ( strcmp("GET", getenv("REQUEST_METHOD")) == 0 )  
    {  
  
        printf("<p>%s</p>", getenv("QUERY_STRING"));  
    }  
    else  
    {  
        nlen = atoi(getenv("CONTENT_LENGTH"));  
        psz_content = ( char * )malloc( nlen + 1 );
        memset( psz_content, 0, nlen + 1 );
        printf("<p>char value:</p><p>");
        for (i = 0; i < nlen; i++ )     
        {  
            psz_content[i] = fgetc(stdin);
            printf( "%c", psz_content[i] );
        }
        printf("</p><p>string value: %s</p>", psz_content);  
    }
    return 0;  
}  

如果是fastcgi可以用以下代码打印环境变量:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  

#include <fcgi_stdio.h>
  
int main()  
{  
    extern char   **environ;  
    int nlen = 0;  
    int i;  
    char *psz_content = NULL;  
    char **pp_env;   

    while(FCGI_Accept() >= 0)
    {
        printf("Content-type: text/html\n\n");  
         
        for ( pp_env = environ; *pp_env; pp_env++ )  
            printf("%s<br>", *pp_env);  
      
        if ( strcmp("GET", getenv("REQUEST_METHOD")) == 0 )  
        {  
      
            printf("<p>%s</p>", getenv("QUERY_STRING"));  
        }  
        else  
        {  
            nlen = atoi(getenv("CONTENT_LENGTH"));  
            psz_content = ( char * )malloc( nlen + 1 );
            memset( psz_content, 0, nlen + 1 );
            printf("<p>char value:</p><p>");
            for (i = 0; i < nlen; i++ )     
            {  
                psz_content[i] = fgetc(stdin);
                printf( "%c", psz_content[i] );
            }
            printf("</p><p>string value: %s</p>", psz_content);  
        }
    }
    return 0;  
}  

注意:

1、这里使用fgetc函数从标准输入读数据,不能使用gets代替

2、FCGX中,头和环境信息在FCGX_Request->envp中,不能用genenv获取,要用FCGX_GetParam获取。


在地址栏 http://localhost/testenv.htm
假设我们输入的用户名和密码分别为abcd和efgh,提交表单之后,在我的机器上显示的结果如下:

COMSPEC=C:\WINDOWS\system32\cmd.exe
CONTENT_LENGTH=31
CONTENT_TYPE=application/x-www-form-urlencoded
DOCUMENT_ROOT=d:/chateaurt4/www
HTTP_ACCEPT=text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
HTTP_ACCEPT_CHARSET=gb2312,utf-8;q=0.7,*;q=0.7
HTTP_ACCEPT_ENCODING=gzip,deflate
HTTP_ACCEPT_LANGUAGE=zh-cn,zh;q=0.5
HTTP_CONNECTION=keep-alive
HTTP_HOST=localhost
HTTP_KEEP_ALIVE=300
HTTP_REFERER=http://localhost/testenv.htm
HTTP_USER_AGENT=Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\MicrosoftVisual Studio\Common\Tools\WinNT;D:\Microsoft VisualStudio\Common\MSDev98\Bin;D:\Microsoft VisualStudio\Common\Tools;D:\Microsoft VisualStudio\VC98\bin;D:\AppServ\Apache2.2\bin;D:\AppServ\php5;D:\AppServ\MySQL\bin
REMOTE_ADDR=127.0.0.1
REMOTE_PORT=1644
SCRIPT_FILENAME=d:/chateaurt4/www/cgi-bin/env.cgi
SERVER_ADDR=127.0.0.1
SERVER_ADMIN=who@where.net
SERVER_NAME=localhost
SERVER_PORT=80
SERVER_SIGNATURE=
Apache/1.3.33 Server at localhost Port 80

SERVER_SOFTWARE=Apache/1.3.33 (Win32)
SystemRoot=C:\WINDOWS
WINDIR=C:\WINDOWS
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.1
REQUEST_METHOD=POST
QUERY_STRING=
REQUEST_URI=/cgi-bin/env.cgi
SCRIPT_NAME=/cgi-bin/env.cgi

usr=abcd&pwd=efgh&submit=Submit


当然不同的机器,它输出的有些结果可能不一样。如果单纯为了输出环境变量,我们可以这样做:
#include <stdio.h>

int main (int argc, char **argv, char **envp)
{
   char **var = envp;
   while (*var)
        printf ("%s \n",*var++);

   return 0;
}

这里面得到的环境变量结果和CGI程序里面的结果差别比较大,因为一个是获得与web应用程序有关的环境变量,而一个获得的是系统的环境变量。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CGI(Common Gateway Interface)是一种通用的Web服务器和应用程序之间的接口标准,它定义了Web服务器如何向外部程序传递数据,以及如何从外部程序获取数据的规范。当Web服务器收到一个CGI请求时,它会启动一个CGI进程来处理该请求,CGI进程将执行一些特定的任务(如生成动态网页),并将结果返回给Web服务器,最终由Web服务器将结果发送给客户端。 FastCGI(Fast Common Gateway Interface)是CGI的改进版,它采用了一种新的进程管理方式,即通过复用已经存在的进程来处理多个请求,避免了每次请求都要启动一个新的CGI进程的开销,从而提高了性能和效率。 下面是它们的区别和联系: 1. 区别:FastCGICGI在进程管理方面的不同 FastCGI采用了一种新的进程管理方式,即用进程池的方式来处理多个请求,而CGI则是每个请求启动一个新的进程。这意味着FastCGI可以避免因频繁启动新进程而造成的性能损失。 2. 区别:FastCGI支持长连接,而CGI不支持 FastCGI支持长连接,即在一次请求中可以发送多个请求,而CGI只支持一次请求一个响应。 3. 联系:FastCGICGI都是Web服务器和应用程序之间的接口标准 无论是FastCGI还是CGI,它们都是Web服务器和应用程序之间的接口标准,用于定义Web服务器如何向外部程序传递数据,以及如何从外部程序获取数据的规范。 总之,FastCGI相对于CGI具有更好的性能和效率,并且支持长连接,但是它们都是Web服务器和应用程序之间的接口标准。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值