CGI编程

CGI(Common Gateway Interface),通用网关接口,它是一段运行在Web服务器上的程序,提供动态网页给客户端。
Silk可以作为CGI程序运行在服务器上,首先确保Web服务器支持CGI并已经配置好CGI,我们以Apache服务器为例。

Apache 配置CGI
以Windows为例,Apache2服务器被解压安装在C:\apache2,编辑C:\apache2\conf下配置文件里的如下部分:
ScriptAlias /cgi-bin/ "c:/apache2/cgi-bin/"

<Directory "c:/apache2/cgi-bin">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>

AddHandler cgi-script .exe .pl .cgi .si

然后双击C:/apache2/bin下的httpd.exe启动Apache服务器。

编写CGI程序
我们使用Silk创建第一个CGI程序,文件名为test.si,把文件复制到Apache的CGI执行目录c:/apache2/cgi-bin中,内容如下:
#!C:\Silk\Silk.exe
//上面第一行为Apache读取CGI解释器所在位置,必须以#!开头
//这里假设silk.exe位于C:\silk下,需根据实际情况做出替换。

main()
{
    printf("Content-type:text/html\n\n");
    printf("This is a Silk CGI program");
}

在浏览器中输入http://127.0.0.1/cgi-bin/test.si测试就可以得到如下结果:
This is a Silk CGI program

CGI环境变量
CGI程序通过接收环境变量来获取浏览器的参数和数据,以及Web服务器的信息。主要环境变量如下:

  • CONTENT_TYPE    这个环境变量的值指示所传递来的信息的MIME类型。
  • CONTENT_LENGTH    如果浏览器发送数据的方式是POST,这个环境变量可以读到POST数据的字节数。
  • HTTP_COOKIE    客户机内的 COOKIE 内容。
  • HTTP_USER_AGENT    提供包含了版本数或其他专有数据的客户浏览器信息。
  • QUERY_STRING    这个环境变量的值即为浏览器中URL所传递的参数信息。
  • REMOTE_ADDR    这个环境变量的值是发送请求的客户机的IP地址。
  • REQUEST_METHOD    浏览器发送数据的方式,一般为 GET 和 POST。
  • SCRIPT_FILENAME    CGI脚本的完整路径
  • SCRIPT_NAME    CGI脚本的的名称
  • SERVER_NAME    这是你的 WEB 服务器的主机名、别名或IP地址。
  • SERVER_SOFTWARE    这个环境变量的值包含了调用CGI程序的HTTP服务器
Silk程序通过如下内置函数读取环境变量和POST数据:
 _fun("getenv", env_name)
getenv为函数名,env_name为环境变量名称。getenv函数可以读取所有环境变量。

_fun("getstdin", length)
getstdin为函数名,length为字节数,即POST数据的大小。getstdin可以读取浏览器发送的POST数据,可以为二进制数据。

_fun("putstdin", data)
putstdin为函数名,data为向浏览器发送的数据,可以为二进制数据。putstdin可以向浏览器发送二进制数据,一般为文件。

下面程序展示了通过getenv函数读取环境变量和POST数据:

#!C:\Silk\Silk.exe
//上面第一行为Apache读取CGI解释器所在位置,必须以#!开头
//Linux下需替换成Linux的Silk解释器位置。

func getenvs()
{
    env={};
    env["REQUEST_METHOD"]=_fun("getenv","REQUEST_METHOD");
    env["CONTENT_LENGTH"]=_fun("getenv","CONTENT_LENGTH");
    env["QUERY_STRING"]=_fun("getenv","QUERY_STRING");
    env["REQUEST_URI"]=_fun("getenv","REQUEST_URI");
    env["REMOTE_ADDR"]=_fun("getenv","REMOTE_ADDR");
    env["SERVER_ADDR"]=_fun("getenv","SERVER_ADDR");
    env["DOCUMENT_ROOT"]=_fun("getenv","DOCUMENT_ROOT");
    env["HTTP_HOST"]=_fun("getenv","HTTP_HOST");
    env["HTTP_CONNECTION"]=_fun("getenv","HTTP_CONNECTION");
    env["HTTP_USER_AGENT"]=_fun("getenv","HTTP_USER_AGENT");
    env["SERVER_SOFTWARE"]=_fun("getenv","SERVER_SOFTWARE");
    
    if(env["REQUEST_METHOD"]=="POST")
    {
        len= _int(env["CONTENT_LENGTH"]);
        env["POST"]=_fun("getstdin",len);//读取POST数据
    }   
    
    return env;
}
main()
{
    printf("Content-type:text/html\n\n");
    env=getenvs();
    
    printf("<html>");
    printf("<h2>CGI Env: </h2>");
    for(i=env.begin();!env.end(i);env.next(i))
    {
        print(env.get(i)[0],"=",env.get(i)[1],"<br/>");
    }
    printf("</html>");
}

Silk语言可以像PHP/ASP一样嵌入HTML中,所以CGI程序中可以把Silk代码通过标记嵌入HTML中生成动态页面。
具体请参考服务器脚本和Silk安装包里的CGI例程。