让 Apache 支持 CGI

让 Apache 支持 CGI

发表于 2017/02/16 更新于 2020/04/27 240 字 1 分钟
AI 摘要 由 AI 自动生成

|

这玩意有一点载入史册的感觉了,首先回答一个问题:CGI 这种东西还健在吗?

测试环境:Apache 2.4.23 (phpStudy) Windows Server 2003

运行脚本:使用 C 语言编写的 CGI 脚本

配置过程

1.加载 CGI 支持模块,打开 Apache 配置文件 (httpd.conf),寻找 LoadModule cgi_module modules/mod_cgi.so 解除前面的 #

2.定义 CGI 运行目录,解除在 Apache 配置文件中 ScriptAlias /cgi-bin/ "D:/phpStudy/Apache/cgi-bin/" 前面的 #,(D:/phpStudy/Apache 根据实际情况而定)

3.启用对 CGI 的支持,解除在 Apache 配置文件中 AddHandler cgi-script .cgi 前面的 #

4.保存

测试

index.html(www 目录) html <body> <form name="form1" action="/cgi-bin/pass.cgi" method="get"> <table align="center"> <tr><td align="center" colspan="2"></td></tr> <tr> <td align="right">用户名</td> <td><input type="text" name="Username"></td> </tr> <tr> <td align="right">密 码</td> <td><input type="password" name="Password"></td> </tr> <tr> <td><input type="submit" value="登 录"></td> <td><input type="reset" value="取 消"></td> </tr> </table> </form> </body> pass.c(编译成 pass.cgi 置于 cgi-bin 目录)

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

     char* getcgidata(FILE* fp, char* requestmethod);
    int main()
    {
                    char *input;
                    char *req_method;
                    char name[64];
                    char pass[64];
                    int i = 0;
                    int j = 0;

     //         printf("Content-type: text/plain; charset=iso-8859-1\n\n");
                    printf("Content-type: text/html\n\n");
                    printf("The following is query reuslt:<br><br>");

                    req_method = getenv("REQUEST_METHOD");
                    input = getcgidata(stdin, req_method);

                    // 我们获取的input字符串可能像如下的形式
                    // Username="admin"&Password="aaaaa"
                    // 其中"Username="和"&Password="都是固定的
                    // 而"admin"和"aaaaa"都是变化的,也是我们要获取的

                    // 前面9个字符是UserName=
                    // 在"UserName="和"&"之间的是我们要取出来的用户名
                    for ( i = 9; i < (int)strlen(input); i++ )
                    {
                                 if ( input[i] == '&' )
                                 {
                                                name[j] = '\0';
                                                break;
                                 }
                                 name[j++] = input[i];
                    }

                    // 前面9个字符 + "&Password="10个字符 + Username的字符数
                    // 是我们不要的,故省略掉,不拷贝
                    for ( i = 19 + strlen(name), j = 0; i < (int)strlen(input); i++ )
                    {
                                 pass[j++] = input[i];
                    }
                    pass[j] = '\0';

                    printf("Your Username is %s<br>Your Password is %s<br> \n", name, pass);

                    return 0;
    }

     char* getcgidata(FILE* fp, char* requestmethod)
    {
                    char* input;
                    int len;
                    int size = 1024;
                    int i = 0;

                    if (!strcmp(requestmethod, "GET"))
                    {
                                 input = getenv("QUERY_STRING");
                                 return input;
                    }
                    else if (!strcmp(requestmethod, "POST"))
                    {
                                 len = atoi(getenv("CONTENT_LENGTH"));
                                 input = (char*)malloc(sizeof(char)*(size + 1));

                                 if (len == 0)
                                 {
                                                input[0] = '\0';
                                                return input;
                                 }

                                 while(1)
                                 {
                                                input[i] = (char)fgetc(fp);
                                                if (i == size)
                                                {
                                                             input[i+1] = '\0';
                                                             return input;
                                                }

                                                --len;
                                                if (feof(fp) || (!(len)))
                                                {
                                                             i++;
                                                             input[i] = '\0';
                                                             return input;
                                                }
                                                i++;

                                 }
                    }
                    return NULL;
    }
    ```

_对于编译 CGI 程序的时候,我使用了 DevC++ 和 gcc,发现放到服务器上跑一直报 500 错误,最后使用了 VC 6.0 编译,试验通过。_

_虽然 CGI 是一种比较好的跨平台脚本,为了更好的兼容性,还是需要注意一下脚本的编译环境吧。_
作者: 小谈谈
声明: 本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。