CGI入门

来源:互联网 发布:金融 大数据 微线索 编辑:程序博客网 时间:2024/05/19 12:15


 @Jan 9, 2014

1        CGI是什么

CGI(Common GatewayInterface)是外部应用与WWW服务器交互的一个标准接口。简单来说,CGI 是一个标准,它定义了浏览器和服务器如何交互,比如浏览器如何向服务器发送消息,而服务器收到消息后又如何进行处理。


既然是一个标准,只要遵循CGI的规范,CGI程序可以用任何语言来编写,如C, C++, VB。Perl语言因其强大的字符串处理能力一度成为编写CGI程序的首选,现在Python语言因在很多方面优于Perl,更是非常适合编写CGI程序。

1.1       工作原理

在服务器上,运行产着一个守护进程对端口进行监听,等待来自客户的请求。当一个请求到来时,将会创建一个子进程为用户的连接服务。根据请求的内容,服务器返回HTML文件或者通过CGI调用外部应用程序并返回处理结果。

1.2       一个CGI程序

在陷入细节之前,一个简单的示例非常有助于理解CGI程序如何工作。

下面是一个非常简单的HelloWorld程序,用C语言实现,浏览器直接请求一个cgi程序获取“hello world”。客户端的操作就是在浏览器输入下面的地址请求内容:

http://127.0.0.1/cgi-bin/helloworld.cgi

 

服务器部署一个HelloWorld.cgi负责执行。

HelloWorld.c

#include <stdio.h>

int main(void)

{

   printf("\n"); //这个必须有

   printf("Hello, World!\n");

    return0;

}

编译后将创建的HelloWorld.exe重命名为HelloWorld.cgi放到服务器的相应目录下。

 

当用户在浏览器中输入上面提到的地址后,服务器会调用HelloWorld.cgi程序并将结果返回给浏览器显示出来。

2        CGI程序编程

浏览器向服务器发送数据时采用编码的形式进行,就是CGI编码。比如下面一个用户填写的用来登录的表单数据,这些数据的名值对会根据它们在表单中的顺序通过“&”连在一起。

Login的表单:

<form method="POST"enctype="multipart/form-data" action="./login.cgi">

用户名: <input type="text" name="user_name"/><br>

密码: <input type="text" name="password"/></br>

<input type="submit"name="login" value="登录">             

</form>

 

URL编码规则:

  • 变量之间用“&”分开;
  • 变量名与变量值用“=”连接; 
  • 空格用“+”代替;
  • 保留的控制字符和特殊字符则用“%”连接对应16进制的ASCII码代替;
  • 空格、任意不可打印的ASCII和控制字符均为非法字符。

 

服务器端CGI程序获取客户端发送的数据有三种途径:环境变量、命令行和标准输入。具体使用哪一种方式根据form的method属性而定。

2.1       Get方法

Get方法通过附加在URL后面的参数发送请求信息,发送的数据长度一般不能超过1024,否则就得使用Post方法。到了服务器后这些信息将被放在环境变量QUERY_STRING中传给CGI程序。当从服务器获取数据而不改变服务器上的数据时,应该选用GET方法。

2.2       Post方法

当浏览器将数据从一个填写的表单传给服务器时一般采用POST方法。当使用POST方法时,Web服务器向CGI程序的标准输入STDIN传送数据。发送的数据长度存在环境变量 CONTENT_LENGTH中。Post方法的数据格式为:

variable1=value1&variable2=value2&etc

 

CGI程序通过检查REQUEST_METHOD环境变量以确定是否采用了POST方法,从而从标准输入读取数据。

2.3       环境变量

环境变量是一个保存信息的内存区。对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。 

当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。 当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了HTTP服务器、客户端、请求等相关的内容,如下面与请求相关的变量:

l REQUEST_METHOD,

l QUERY_STRING,客户端采用Get方法发送的数据

l CONTENT_LENGTH ,STDIO中的有效信息长度

2.4       获取数据

当客户通过浏览器发出CGI请求时,服务器在调用CGI程序时,服务器把该用户的信息保存到环境变量里。

CGI程序通过读取环境变量REQUEST_METHOD的值来确定通过何种方式获取请求数据。

下面的代码演示了这一过程:

 

#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;

       

        if (!strcmp(method, ”POST”)) {

                 length = atoi(getenv(“CONTENT_LENGTH”));

                 if (length != 0) {

                         inputstring = malloc(sizeof(char) * length + 1)

                         //必须申请缓存,因为stdin是不带缓存的。

                         fread(inputstring, sizeof(char), length, stdin);

                 }

        }

        elseif (!strcmp(method, “GET”)) {

                 Inputstring = getenv(“QUERY_STRING”);

                 length = strlen(inputstring);

        }

       

        return length;

}

使用数据需要对得到的字符串进行解码,也就是把“value=1&value2=2”这样的字符串转换为可以使用的单个变量。

 

现在一般都有成熟的库来做这些事情,只需要调用相关的api就可以了。

2.5       返回结果

上面已经看到过,CGI程序通过stdout将信息处理结果返回给客户端,这个输出需要符合CGI格式。

int main(void)

{

   printf("\n"); //这个必须有

   printf("Hello, World!\n");

    return0;

}

 

在CGI程序中的标准输出stdout是经过重定义了的,它并没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器,这与它是由C,还是Perl或Python实现无关,如C使用printf向该进程的标准输出发送数据,Perl和Python用print向该进程的标准输出发送数据。所以我们可以用打印来实现客户端新的HTML页面的生成。

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

2.6       CGI的C语言库

前面提到有现成CGI库来做数据获取、解析和输出工作,如CgiHtml和CGIC。

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

  • Read_cgi_input():获取并解析HTML表单输入,返回一个指向某结构体的指针  
  • Cgi_val():获取每个表单变量的值  
  • Html_header():输出HTML标题栏 
  • Html_begin():输出HTML文档的开始部分  
  • H1():输出一行字符,字体为H1 
  • Html_end():输出HTML文档的结尾部分

这里使用的是CGIC,后面会继续介绍。


后续见

CGI入门(续)


0 0
原创粉丝点击