试用EF开发WEB应用程序(8): CGI环境变量

23 篇文章 0 订阅
22 篇文章 0 订阅

题记:用“易语言.飞扬”(EF)开发WEB应用程序,此前还没有先例。但因为EF本地开发包(EFNDK)已经发布,用C/C++开发一个EF类库,使其支持EF开发WEB应用程序,应该并非难事。当然也可想而知,其中必有诸多难点有待解决。此系列文章,为本人探索过程之记录,对外人未必有多大价值。如有网友乐观其事,还请理性待之。作者:liigo。转载请务必注明出处:http://blog.csdn.net/liigo/在线留言


试用EF开发WEB应用程序(8): CGI环境变量 

  FastCGI 是对 CGI 技术的扩展和改进,要写好 FastCGI / CGI 程序,了解、熟悉、深入掌握“CGI环境变量”是必需的。本文将重点介绍CGI规范中规定的标准环境变量,以及FastCGI扩展的环境变量。

  在 CGI / FastCGI 规范中,WEB服务器和CGI/FastCGI程序之间交流信息的主要途径是环境变量(以及标准输入输出流)。这里说到的环境变量,是指操作系统中的环境变量。(Windows系统下,PATH 是很常见的一个环境变量;熟悉JAVA的朋友通常都知道一个叫 CLASSPATH 的环境变量;学“易语言.飞扬”(EF) 的哥们也肯定听说过 EF_LIB_PATHS 这个环境变量;……) CGI规范对CGI程序中使用的环境变量名称及其含义做了具体而明确的规定,通常把这些环境变量称为“CGI环境变量”。

下表:CGI环境变量及其介绍

CGI 环境变量名称说明
REQUEST_METHOD请求类型,如 "GET" 或 "POST"
CONTENT_TYPE被发送数据的类型
CONTENT_LENGTH客户端向标准输入设备发送的数据长度,单位为字节
QUERY_STRING查询参数,如 "id=10010&sn=liigo"
SCRIPT_NAMECGI脚本程序名称,如 "/xyz.efcgi"
PATH_INFOCGI脚本程序的附加路径
PATH_TRANSLATEDPATH_INFO对应的绝对路径
REMOTE_ADDR发送此次请求的主机IP
REMOTE_HOST发送此次请求的主机名
REMOTE_USER已被验证合法的用户名
REMOTE_IDENTWEB服务器的登录用户名
AUTH_TYPE验证类型
GATEWAY_INTERFACE服务器遵守的CGI版本,如 "CGI/1.1"
SERVER_NAME服务器主机名、域名或IP
SERVER_PORT服务器端口号
SERVER_PROTOCOL服务器协议,如 "HTTP/1.1"
SERVER_SOFTWARE服务器软件的描述文本
DOCUMENT_ROOT文档根目录
HTTP_ACCEPT客户端可以接收的MIME类型,以逗号(,)分隔
HTTP_USER_AGENT发送此次请求的WEB浏览器
HTTP_REFERER调用此脚本程序的文档
HTTP_COOKIE获取COOKIE键值对,多项之间以分号(;)分隔,如 "key1=value1; key2=value2"

下表:FastCGI 扩展的环境变量

FastCGI 环境变量名称说明
FCGI_ROLE当前 FastCGI 程序担任的角色,如 "RESPONDER", "AUTHORIZER", "FILTER"
FCGI_DATA_LENGTH服务器发送的数据长度。仅当 FCGI_ROLE 值为 "FILTER" 时有效。
FILE_LAST_MOD输入文件(input file)的最后修改时间,其值为自1970年1月1日零时零分零秒(世界标准时间,UTC)至今的秒数。仅当 FCGI_ROLE 值为 "FILTER" 时有效。

 

  对于以上所有 CGI 环境变量,和 FastCGI 扩展的环境变量,EF类库 fastcgi.efn 中的 FCGI 类均提供同名属性方法,用于读取该环境变量的值。一般来说,这些方法返回文本数据;只有几个例外,是返回整数数据:CONTENT_LENGTH(), FCGI_DATA_LENGTH(), FILE_LAST_MOD()。

  此外,WEB服务器通常也会扩展一些环境变量,这种情况下,可用EF类库 fastcgi.efn 中提供的 FCGI.getenv() 方法读取任意指定名称的环境变量的值。

 

  下面,我们用EF写一个WEB程序,列出以上所有CGI环境变量及其内容,亲身感受一下CGI环境变量的真实面目,以便加深对它们的理解:

引入 fastcgi;

公开 类 启动类
{
    常量 文本 s 
=  [ " Content-type: text/html

< html >< head >
< meta http - equiv = " content-type "  content = " text/html;charset=utf-8 " >
< title > $(title) </ title >
</ head >
< body >
< h1 > $(title) </ h1 >
< hr ></ hr >
< h3 > PARAMS:  </ h3 >
< p > $(params) </ p >
< hr ></ hr >
< h3 > CGI ENV VARS:  </ h3 >
< p > $(cgivars) </ p >
< hr ></ hr >
< p > by liigo, index: $(index) </ p >
</ body >
</ html >
" ];
    
    公开 静态 启动()
    {
        
int  count  =   0 ;
        FCGI fcgi 
=   new  FCGI;
        
while (fcgi.Accept()  >=   0 )
        {
            文本 t  =  s.替换全部( " $(title) " " CGI VARS (by liigo) " );
            t 
=  t.替换( " $(params) " , get_params(fcgi));
            t 
=  t.替换( " $(cgivars) " , get_cgivars(fcgi));
            t 
=  t.替换( " $(index) " , count.到文本());
            fcgi.Output(t.到UTF8());
            count
++ ;
        }
    }

    
static  string get_params(FCGI fcgi)
    {
        string s;
        foreach (fcgi.QUERY_STRING_NAMES(), 文本 name)
        {
            s 
+=   " <p> "   +  name  +   " "   +  fcgi.QUERY_STRING(name)  +   " </p> " ;
        }
        
return  s;
    }
    
    
static  string get_cgivars(FCGI fcgi)
    {
        string s;

        s 
+=   " <p>REQUEST_METHOD:  "   +  fcgi.REQUEST_METHOD  +   " </p> " ;        
        s 
+=   " <p>CONTENT_TYPE:  "   +  fcgi.CONTENT_TYPE  +   " </p> " ;
        s 
+=   " <p>CONTENT_LENGTH:  "   +  fcgi.CONTENT_LENGTH.到文本()  +   " </p> " ;
        
if (fcgi.CONTENT_LENGTH  >   0 )
        {
            binary content 
=  fcgi.ReadData(fcgi.CONTENT_LENGTH);
            s 
+=   " <p>CONTENT:  "   +  content.到文本()  +   " </p> " ;
            s 
+=   " <p>CONTENT(text): </p><p> "   +  content.UTF8到文本().替换全部( " " " <br/> " +   " </p> " ;
        }
        s 
+=   " <p>QUERY_STRING:  "   +  fcgi.QUERY_STRING  +   " </p> " ;
        s 
+=   " <p>QUERY_STRING_NAMES:  "   +  fcgi.QUERY_STRING_NAMES().到文本()  +   " </p> " ;
        s 
+=   " <p>QUERY_STRING_UNDECODED:  "   +  fcgi.QUERY_STRING_UNDECODED  +   " </p> " ;
        s 
+=   " <p>SCRIPT_NAME:  "   +  fcgi.SCRIPT_NAME  +   " </p> " ;
        s 
+=   " <p>PATH_INFO:  "   +  fcgi.PATH_INFO  +   " </p> " ;
        s 
+=   " <p>PATH_TRANSLATED:  "   +  fcgi.PATH_TRANSLATED  +   " </p> " ;
        s 
+=   " <p>REMOTE_ADDR:  "   +  fcgi.REMOTE_ADDR  +   " </p> " ;
        s 
+=   " <p>REMOTE_HOST:  "   +  fcgi.REMOTE_HOST  +   " </p> " ;
        s 
+=   " <p>REMOTE_USER:  "   +  fcgi.REMOTE_USER  +   " </p> " ;
        s 
+=   " <p>REMOTE_IDENT:  "   +  fcgi.REMOTE_IDENT  +   " </p> " ;
        s 
+=   " <p>AUTH_TYPE:  "   +  fcgi.AUTH_TYPE  +   " </p> " ;
        
        s 
+=   " <p>GATEWAY_INTERFACE:  "   +  fcgi.GATEWAY_INTERFACE  +   " </p> " ;
        s 
+=   " <p>SERVER_NAME:  "   +  fcgi.SERVER_NAME  +   " </p> " ;
        s 
+=   " <p>SERVER_PORT:  "   +  fcgi.SERVER_PORT.到文本()  +   " </p> " ;
        s 
+=   " <p>SERVER_PROTOCOL:  "   +  fcgi.SERVER_PROTOCOL  +   " </p> " ;
        s 
+=   " <p>SERVER_SOFTWARE:  "   +  fcgi.SERVER_SOFTWARE  +   " </p> " ;
        s 
+=   " <p>DOCUMENT_ROOT:  "   +  fcgi.DOCUMENT_ROOT  +   " </p> " ;

        s 
+=   " <p>HTTP_ACCEPT:  "   +  fcgi.HTTP_ACCEPT  +   " </p> " ;
        s 
+=   " <p>HTTP_USER_AGENT:  "   +  fcgi.HTTP_USER_AGENT  +   " </p> " ;
        s 
+=   " <p>HTTP_REFERER:  "   +  fcgi.HTTP_REFERER  +   " </p> " ;
        s 
+=   " <p>HTTP_COOKIE:  "   +  fcgi.HTTP_COOKIE  +   " </p> " ;
        
        s 
+=   " <p>FCGI_ROLE:  "   +  fcgi.FCGI_ROLE  +   " </p> " ;
        s 
+=   " <p>FCGI_DATA_LENGTH:  "   +  fcgi.FCGI_DATA_LENGTH.到文本()  +   " </p> " ;
        s 
+=   " <p>FILE_LAST_MOD:  "   +  fcgi.FILE_LAST_MOD.到文本()  +   " </p> " ;

        
return  s;
    }
}

下图是以上程序的执行结果(左图由URL提交,右图由FORM提交(<form action = "cgivars.efcgi" method="post" enctype="multipart/form-data">)),近距离感受它们吧(点击放大图片):

  

参考:

http://www.fastcgi.com

http://hoohoo.ncsa.uiuc.edu/cgi/ 

 

下篇预告:??? 


 一点题外话:上面提到JAVA使用了一个叫 CLASSPATH 的环境变量,我一直觉得这个环境变量的名称取得“太霸道”,你凭什么把这样一个“通用名称”占用了呀,怎么说也该加上一个"JAVA" 或 "J" 前缀吧:JAVA_CLASSPATH, J_CLASSPATH。要不然,后面再出来几个编程语言,也需要使用“类路径”之类的环境变量的话,让人家做何选择?呵呵。相对来说,“易语言.飞扬”就厚道一些,使用了“EF_LIB_PATHS”,加了自己的前缀(EF)。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值