CGI详解

一、环境变量

对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。

1.与请求相关的环境变量

  • REQUEST_METHOD -服务器与CGI程序之间的信息传输方式
  • QUERY_STRING - 采用GET时所传输的信息
  • CONTENT_LENGTH -STDIO中的有效信息长度
  • CONTENT_TYPE -指示所传来的信息的MIME类型
  • CONTENT_FILE -使用Windows HTTPd/WinCGI标准时,用来传送数据的文件名
  • PATH_INFO -路径信息
  • PATH_TRANSLATED -CGI程序的完整路径名
  • SCRIPT_NAME -所调用的CGI程序的名字

2.与服务器相关的环境变量

  • GATEWAY_INTERFACE -服务器所实现的CGI版本

  • SERVER_NAME -服务器的IP或名字

  • SERVER_PORT -主机的端口号

  • SERVER_SOFTWARE -调用CGI程序的HTTP服务器的名称和版本号

3.与客户端相关的环境变量

  • REMOTE_ADDR 客户机的主机名

  • REMOTE_HOST 客户机的IP地址

  • ACCEPT 列出能被次请求接受的应答方式

  • ACCEPT_ENCODING 列出客户机支持的编码方式

  • ACCEPT_LANGUAGE 表明客户机可接受语言的ISO代码

  • AUTORIZATION 表明被证实了的用户

  • FORM 列出客户机的EMAIL地址

  • IF_MODIFIED_SINGCE 当用get方式请求并且只有当文档比指定日期更早时才返回数据

  • PRAGMA 设定将来要用到的服务器代理

  • REFFERER 指出连接到当前文档的文档的URL

  • USER_AGENT 客户端浏览器的信息

二、POS/GETT方法

1. post

如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purpose Internet Mail Extensions)。目前,MIME类型一般是:application/x-wwww-form-urlencoded,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。
##2. get
在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。

据附加到由ACTION标记命名的URL的末尾,用一个问号把经过URL编码后的信息与CGI程序的名字分开:http://www.mycorp.com/hello.html?name=hgq$id=1,QUERY_STRING的值为name=hgq&id=1

3.POST与GET的区别

以 GET 方式接收的数据是有长度限制,而用 POST 方式接收的数据是没有长度限制的。并且,以 GET 方式发送数据,可以通过URL 的形式来发送,但 POST方式发送的数据必须要通过 Form 才到发送。

三.CGI程序实现步骤

C语言实现代码:

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

int get_inputs()
{
int length;
char *method;
char *inputstring;

method = getenv(“REQUEST_METHOD”); //将返回结果赋予指针
if(method == NULL)
    return 1;       //找不到环境变量REQUEST_METHOD
if(!strcmp(method, ”POST”))  // POST方法
{
    length = atoi(getenv(“CONTENT_LENGTH”)); //结果是字符,需要转换
    if(length != 0)
    {
        inputstring = malloc(sizeof(char)*length + 1) //必须申请缓存,因为stdin是不带缓存的。
        fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据
}
}
else if(!strcmp(method, “GET”))
{
    Inputstring = getenv(“QUERY_STRING”);   
    length = strlen(inputstring);
}
if(length == 0)
return 0;
}

PYTHON代码实现:

#!/usr/local/bin/python
import cgi
def main():
form = cgi.FieldStorage()

 

Python代码实现更简单,cgi.FieldStorage()返回一个字典,字典的每一个key就是变量名,key对应的值就是变量名的值,更本无需用户再去进行数据解码!

三.CGI数据输出

在CGI程序中的标准输出stdout是经过重定义了的,它并没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器,这与它是由C,还是Perl或Python实现无关。

所以,我们可以用打印来实现客户端新的HTML页面的生成。比如,C的printf是向该进程的标准输出发送数据,Perl和Python用print向该进程的标准输出发送数据。

1.cgi标题

CGI的格式输出内容必须组织成标题/内容的形式。CGI标准规定了CGI程序可以使用的三个HTTP标题。标题必须占据第一行输出!而且必须随后带有一个空行。

2. MIME

MIME类型以类型/子类型(type/subtype)的形式表示。
其中type表示一下几种典型文件格式的一种:
Text、Audio、Video、Image、Application、Mutipart、Message

Subtype则用来描述具体所用的数据格式。

例如Perl和Python:

print “Content-type:text/html\n\n”;   //输出HTML格式的数据
print “<body>welcome<br>”
print “</body>”

C语言:

printf( “Content-type:text/html\n\n”);
printf(“Welcome\n”);

3. Location

使用Location标题,一个CGI可以使当前用户转而访问同一服务器上的另外一个程序,甚至可以访问另外一个URL,但服务器对他们的处理方式不一样

使用Location的格式为:Location:Filename/URL,例如:

print “Location:/test.html\n\n”;
这与直接链接到test.html的效果是一样的。



print “Location:http://www.chinaunix.com/\n\n”
由于该URL并不指向当前服务器,用户浏览器并不会直接链接到指定的URL,而是给用户输出提示信息。

4. HTTP状态码

表示了请求的结果状态,是CGI程序通过服务器用来通知用户其请求是否成功执行的信息码,本文不做研究。

四、设置HTTP服务器以兼容CGI

用Perl编写的CGI程序后缀为:.pl;Python编写的CGI程序后缀为:.py;而C编写的CGI程序后缀为:.cgi,如果在win下编译出来的是.exe,最好将它重命名为.cgi。这些都是为了HTTP服务能够识别并调用它们。

五、关于CGI的C语言库——cgihtml

Cgihtml是一个应用非常广泛的C语言编写的CGI库。它提供的功能函数如下:

Read_cgi_input():获取并解析HTML表单输入,返回一个指向某结构体的指针

Cgi_val():获取每个表单变量的值

Html_header():输出HTML标题栏

Html_begin():输出HTML文档的开始部分

H1():输出一行字符,字体为H1

Html_end():输出HTML文档的结尾部分。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×