CGI 全称为Common Gateway Interface (通用网关接口),目的是能够让服务器能够方便的调用外部程序。

CGI本身是一套协议和规范,原则上只要是拥有读写文件功能的编程语言都可以用来编写CGI程序,例如C,C++,Perl,Visual Basic,Shell等等,历史上用来编写CGI程序使用最广泛的是Perl语言,连PHP一开始也是用Perl编写的,估计也受这个传统的影响。服务器在认为这是一个CGI请求时,会调用相关CGI程序,并通过环境变量和标准输出将数据传送给CGI程序,CGI程序处理完数据,生成html,然后再通过标准输出将内容返回给服务器,服务器再将内容交给用户,CGI进程退出,在这个过程中,服务器的标准输出对应了CGI程序的标准输入,CGI程序的标准输出对应着服务器的标准输入,相当于利用两条管道建立了进程间的通信。

CGI程序可能会调用其它应用或API来完成用户提交的请求。

 

现在CGI一般不再用于直接返回html页面,同时将复杂的计算、IO任务下沉到后端。使CGI作为前后端之间的中间层。彼时CGI的职能是完成基本的数据交换:解析前端数据请求,再转发给对应后端;然后从后端取回数据,给前端返回XML或JSON。

WEB通用网关接口:CGI简单教程

 

参考:

 

 

 

测试环境:Ubuntu gnome(16.04)版 + win10  (win10上运行Ubuntu虚拟机)

 

1. 安装thttpd

参考:https://blog.csdn.net/u012247418/article/details/90137417

 

 

2. 编写index.html

<h1>A Simple CGI Test</h1>  
<form action="/cgi-bin/test-cgi.cgi" method="get">  
<table>  
    <tr>  
        <td>User Name: </td>  
        <td><input name="username"/></td>  
    </tr>  
        <tr>  
        <td>Password: </td>  
        <td><input name="password"/></td>  
    </tr>  
    <tr>  
        <td><input type="submit" value="OK"/></td>  
    </tr>  
    </table>  
</form>

利用GET向服务器发送请求,并将用户数据(Name&Password)作为URL的一部分发送到服务器。

 

 

3. 编写CGI程序

CGI程序可以用多种语言来编写,当然也包括C/C++。

1) test-cgi.c

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


int main(int argc, char *argv[])
{
    char *query_string = "FAILD";

    char *request_mthod = getenv("REQUEST_METHOD");
    if((request_mthod != NULL) && (strncmp(request_mthod, "GET", 3) == 0))
    {
        query_string = getenv("QUERY_STRING");
    }

    printf("Content-type:text/html\n\n");
    printf("<html>\n");
    printf("<head><title>An html page from a cgi</title></head>\n");
    printf("<body>\n");
    printf("<h1>query string: %s</h1>\n", query_string);
    printf("</body>\n");
    printf("</html>\n");

    fflush(stdout);
    return 0;
}

先判断客户端请求是否为“GET”,如果是则获取请求参数,最后将请求参数再原封不动的返回至客户端。

 

2) 编译:gcc test-cgi.c -o test-cgi.cgi

 

 

4. 修改配置

4.1 创建目录

[email protected]:~/tools/thttpd/html1$ tree

.

├── cgi-bin

│   └── test-cgi.cgi

└── index.html

 

1 directory, 2 files

 

4.2 修改thttpd.conf

# This section overrides defaults
dir=/home/baoli/tools/thttpd/html1
# chroot
user=baoli# default = nobody
logfile=/var/log/thttpd.log
pidfile=/var/run/thttpd.pid
# This section _documents_ defaults in effect
# port=80
# nosymlink# default = !chroot
# novhost
cgipat=/cgi-bin/*
# nothrottles
# host=0.0.0.0
# charset=iso-8859-1

 

说明:

1)cgipat=/cgi-bin/*

声明CGI程序的目录,这里的'/'根目录并非Ubuntu系统的根目录,而是以dir=/home/baoli/tools/thttpd/html1 作为根目录。

2)屏蔽chroot是为了运行动态编译的CGI程序

 

 

5. 测试

在windows 浏览器输入:http://192.168.0.104

WEB通用网关接口:CGI简单教程

 

 

 

6. CGI环境变量

环境变量

意义

SERVER_NAME

CGI脚本运行时的主机名和IP地址.

SERVER_SOFTWARE

你的服务器的类型如: CERN/3.0 或 NCSA/1.3.

GATEWAY_INTERFACE

运行的CGI版本. 对于UNIX服务器, 这是CGI/1.1.

SERVER_PROTOCOL

服务器运行的HTTP协议. 这里当是HTTP/1.0.

SERVER_PORT

服务器运行的TCP口,通常Web服务器是80.

REQUEST_METHOD

POST 或 GET, 取决于你的表单是怎样递交的.

HTTP_ACCEPT 

浏览器能直接接收的Content-types, 可以有HTTP Accept header定义.

HTTP_USER_AGENT

递交表单的浏览器的名称、版本 和其他平台性的附加信息。

HTTP_REFERER

递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它

PATH_INFO

附加的路径信息, 由浏览器通过GET方法发出.

PATH_TRANSLATED

在PATH_INFO中系统规定的路径信息.

SCRIPT_NAME

指向这个CGI脚本的路径, 是在URL中显示的(如, /cgi-bin/thescript).

QUERY_STRING

脚本参数或者表单输入项(如果是用GET递交). QUERY_STRING 包含URL中问号后面的参数.

REMOTE_HOST

递交脚本的主机名,这个值不能被设置.

REMOTE_ADDR

递交脚本的主机IP地址.

REMOTE_USER

递交脚本的用户名. 如果服务器的authentication被**,这个值可以设置。

REMOTE_IDENT

如果Web服务器是在ident (一种确认用户连接你的协议)运行, 递交表单的系统也在运行ident, 这个变量就含有ident返回值.

CONTENT_TYPE

如果表单是用POST递交, 这个值将是 application/x-www-form-urlencoded. 在上载文件的表单中, content-type 是个 multipart/form-data.

CONTENT_LENGTH

对于用POST递交的表单, 标准输入口的字节数.

 

关于GET和POST

表单从浏览器发给服务器有两种方法.  GET 和 POST.

  我们上面谈论的方法,实际是GET,它将数据打包放置在环境变量QUERY_STRING中作为URL整体的一部分传递给服务器。

  POST做很多类似GET同样的事情, 不同的地方就是它是分离地传递数据给脚本. 你的脚本通过标准输入获取这些数据. (有些Web服务器是存储在临时文件中.) 这个QUERY_STRING环境变量将不再设置.

  那你用那个方法呢? POST是个安全的方法, 尤其如果你的表单中有很多数据的话. 当你用GET, 这个服务器就分配变量QUERY_STRING给所有的表单数据, 但是这个变量可存储量是有限的. 换句话说,如果你有很多数据但是你又用GET,你会丢失很多数据.

 

 

相关文章: