CGI入门(续)

 @Jan 9, 2014

前接CGI入门

1        环境搭建

这里使用的环境是OS: Win7,服务器:Apache Httpd,编程语言:C,编程工具C-Free,

Linux系统可以使用服务器Boa。

1.1       下载C-Free编译器

C-Free是一款支持多种编译器的专业化C/C++集成开发环境(IDE)。利用本软件,使用者可以轻松地编辑、编译、连接、运行、调试C/C++程序。下载地址:

http://www.programarts.com/服务器

1.1.1     下载Apache Http Server (Apache Httpd)

下载地址http://httpd.apache.org/

下载binary,打开下面win32文件夹中的某个版本,如下面的

httpd-2.0.65-win32-x86-openssl-0.9.8y.msi (带ssl)

或者httpd-2.0.65-win32-x86-no_ssl.msi   (不带ssl)

带SSL表示可以配置SSL安全链接,即Https

 

Binary 目录

1.1.2     安装Apache Http Server

  “Network Domain”填写你的网络域名,如果没有网络域名,可以随便填写。但如果你架设的 Apache 服务器如果要放入Internet ,则一定要填写正确的网络域名。在“Server Name”下填入你的服务器名,也就是主机名。“Administrator's Email Address”填写系统管理员的联系电子邮件地址。上述三条信息三条信息均可任意填写,无效的也行,其中联系电子邮件地址会在当系统故障时提供给访问者。

http://jingyan.baidu.com/article/e4d08ffdc1ab5b0fd2f60df4.html

 

1.1.3     端口冲突

 

安装之后,我们占用80端口,或者8080端口,有时候会因为端口冲突而造成无法启动apace2.2。

需要将c:\apache\conf\httpd.conf中的配置进行更改,将其中的Listen8080 或者Listen 80,更改为 Listen 50080。

这是由于windows IIS中的Web服务器默认情况下在TCP 80端口监听连接请求,而8080端口一般留给代理服务器使用,所以为了避免Apache web 服务器的监听端口与其发生冲突,将Apache Web服务器的监听端口修改为不常用的高端端口50080。

在浏览器中进行访问时,应使用http://localhost:50080/即可。

http://blog.163.com/xiaoyang_80/blog/static/1723721352010111392055674/

 

1.1.4     配置Apache Http Server

配置Apache以支持CGI程序

打开Apache安装目录下的\conf\httpd.conf文件,找到下面一句

 

修改apache的配置文件httpd.conf:

将下面的
<Directory "D:/Apache Group/Apache2/cgi-bin">

   AllowOverride None

    OptionsNone

    Orderallow,deny

    Allowfrom all

</Directory>

#AddHandler cgi-script .cgi

改为:

<Directory "D:/ApacheGroup/Apache2/cgi-bin">

   AllowOverride None

   Options ExecCGI

    Orderallow,deny

    Allowfrom all

</Directory>

AddHandler cgi-script .cgi .pl

 

注意:用C语言编写的CGI程序后缀是.cgi,Perl编写的后缀是.pl,Python编写的后缀是.py。

 

如果还想要修改cgi程序存放的目录,将下面的

ScriptAlias /cgi-bin/ "D:/Program Files(x86)/Apache Group/Apache2/cgi-bin/"

改为

ScriptAlias /somepath/ "D:/Program Files (x86)/ApacheGroup/Apache2/cgi-bin/"

 

修改请求目录时默认显示的文件

请求某个目录时,默认显示的文件是index.html , index.html.var .

要修改为其他文件,找到httpd.conf中的下面这一行:

DirectoryIndex index.html index.html.var

 

将上面的index.html index.html.var 修改为想要显示的其他文件的名字,如下面:

DirectoryIndexindex.html index.htm default.htm index.php index.pl

甚至可以是子目录下的

DirectoryIndexindex.html index.pl /nav/index.php

 

然后重启服务器

 

参考:Apache Display / Change a Default Page Other Than index.html.

http://www.cyberciti.biz/faq/apache-display-or-change-a-default-page-other-than-indexhtml/

1.1.5     测试

运行一个helloword的CGI程序

 

(参考

http://wenku.baidu.com/link?url=diPr7kr9c74xhkcCVYmcXFpxChuSw8bv_dHtPHQDE2iwesfsX8nItBiJiTcx4gLQpEXF234DF1ElXqcDt6B3N-ZwCNGrUO1dgEMYSeeifsm

 

官方文档Dynamic content with CGI. http://httpd.apache.org/docs/2.2/howto/cgi.html)

 

写一个HelloWorld.c的cgi,代码如下:

 

#include <stdio.h>

int main(void)

{

   printf("Content-Type:text/html; charset=gb2312;\n\n");//后面必须加两个回车

 

   printf("<html>");

    printf("<head><title>Hello</title></head>\n<body>\n")

    printf("<h3>Hello World </h3>\n");

    return0;

}

 

编译后成了HelloWorld.exe,重命名为HelloWorld.cgi复制到apache的cgi-bin目录下

注意:

1)用VC编译可以保证正常运行,用Turboc2编译会出现错误,无法执行,原因可能是后者为16位编译器,前者为32位编译器的缘故。

2)必须首先输出一个空行,如果不输出该空行,则会出现题为“Internal Server Error”的错误,所以第一行的printf("\n");这个必须有。

 

运行程序时,打开网页,在地址栏中输入下面的网址:

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

浏览网页看结果。

2        CGIC库的使用

所有的CGI程序都必须执行一些特定的工作,如解析表单数据,CGIC库提供了这样的一些API。

2.1       下载CGIC

从以下网址下载CGIC库:

www.boutell.com/cgic/#obtain

 

2.2       创建一个sample application

CGIC库自带了一个程序cgitest.c,

参考

CGIC简明教程目录(CGI篇)

http://wenku.baidu.com/view/3c8bb1d126fff705cc170aac.html

 

创建一个cgitest工程,包含cgitest.c, cgi.c, cgi.h三个文件,编译后将重名为.cgi并拷贝到apache的cgi-bin目录下,用http://localhost/cig-bin/cgitest.cgi进行测试。

这是一个表但提交程序,提交后会显示提交的内容:

 

Cgitest界面

2.3       编写使用CGIC库的程序

CGIC库提供了自己的main()函数。使用该库时,不需要写main函数,而是要写一个cgiMain()函数,该函数会在初始cgi工作完成后被激活。程序需要include头文件cgi.h文件。如果要修改默认的main函数的行为可以修改cgi.c中的main()函数。

2.4       获取URL参数

通过JavaScript提交表单时,参数可以跟在url后面,这时需要将方法设为GET,然后使用CGIC的API获取这些参数。

调试时,为了检查传入的参数是否正确,可以在CGIC程序里引入下面的变量,然后查看该变量即可,该变量包含了URL带的原始参数。

#include  “cgic.h”

extern char *cgiQueryString;

 

int main() {…}

3        Errors Shooting

3.1       502 Bad Gateway The CGI was notCGI/1/1 compliant

访问Ubuntu下BOA中的CGI程序,提示” 502 Bad Gateway The CGI was not CGI/1/1 compliant”,

Server log显示 “cgi-header:unable to find LFLF”。

 

没有成功执行CGI程序,这可能是由于CGI程序不存在或权限不够造成,如果是权限不够,赋予该cgi执行权限:chmod 777 file_name.cgi

 

参考:

CGI和BOA使用期间遇到的问题汇总(转).

http://www.cnblogs.com/hnrainll/archive/2011/06/01/2067295.html

 

3.2       400 Bad Request

CGI程序在Windows下的 ApacheServer中运行正确,布署到Ubuntu虚拟机的BOA Server后,访问CGI程序,返回的response(request.responseText,使用Ajax发送POST的异步请求)提示”400 Bad request”错误。

 

Server Log提示错误:”InvalidContent-Length [0] on POST!”,在Ubuntu虚拟机中访问和Windows(IE和Firefox)访问结果一样。

 

请求方法改为”GET”后OK。

 

其他相关错误

http://stackoverflow.com/questions/328281/why-content-length-0-in-post-requests

 

Invalid Content-LengthHeader May Cause Requests to Fail Through ISA Server.

http://support.microsoft.com/kb/300707  该文的错误原因是由于某些浏览器加了两个字符(回车和换行)在消息体的末尾,但却没有在HTTP request的content-length中体现这两个字符,导致实际内容长度大于content-length。

4        附

4.1       CGI环境变量

 

与请求相关的环境变量

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程序的名字

与服务器相关的环境变量

GATEWAY_INTERFACE

服务器所实现的CGI版本

SERVER_NAME

服务器的IP或名字

SERVER_PORT

主机的端口号

SERVER_SOFTWARE

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

与客户端相关的环境变量

REMOTE_ADDR

客户机的主机名

REMOTE_HOST

客户机的IP地址

ACCEPT

例出能被次请求接受的应答方式

ACCEPT_ENCODING

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

ACCEPT_LANGUAGE

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

AUTORIZATION

表明被证实了的用户

FORM

列出客户机的EMAIL地址

IF_MODIFIED_SINGCE

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

PRAGMA

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

REFFERER

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

USER_AGENT

客户端浏览器的信息

        CONTENT_TYPE:如application/x-www-form-urlencoded,表示数据来自HTML表单,并且经过了URL编码。

ACCEPT:客户机所支持的MIME类型清单,内容如:”image/gif,image/jpeg”

REQUEST_METHOD:它的值一般包括两种:POST和GET,但我们写CGI程序时,最后还要考虑其他的情况。

 

4.2       解析数据

 

/*function getPOSTvars*/

char **getPOSTvars(){

        int i;

        int content_length;

        char **postvars;

        char *postinput;

        char **pairlist;

        int paircount=0;

        chr*nvpair;

        char *eqpos;

        postinput=getenv("CONTENT_LENGTH");//获取传送给程序数据的字节数

        if(!postinput)

                 exit();

        if(!content_length=atoi(postinput))) //获取信息长度¨

                 exit(1);

        if(!(postinput=(char*)malloc(content_length+1)))

                 exit(1);

        if(!fread(postinput,content_length,1,stadin))

                 exit(1);

        postinput[content_length]='0';

        for(i=0;postinput[i];i++)

                 if(postinput[i]=='+')

                         postinput[i]=''; //对加易进行处理

        pairlist=(char **)malloc(256*sizeof(char **));

        paircount=0;

        nvpair=strtok(postinput,"&"); //从出现“&amp;”字符的位置把信息分段,然后对结果依次处理

        while (nvpair){

                 pairlist[paircount++]=strdup(nvpair);

                 if(!(paircount%256))

                         pairlist=(char**)realloc(pairlist,(paircount+256)*sizeof(char**));

                 nvpair=strtok(NULL,"&");

        }

        pairlist[paircount]=0;

        postvars=(char**)malloc((paircount*2+1)*sizeof(char **));

        for(i=0;i<paircount;i++){

                 if(eqpos=strchr(pairlist[i],'=')){

                         *eqpos='0';

                         unescape_url(postvars[i*2+1]=strdup(eqpos+1));//调用unescape_url函数继续解码

                 }else{

                         unescape_url(postvars[i*2+1])=strdup(""));

                 }

                 postvars[paircount*2]=0;

                 for(i=0;pairlist[i];i++)

                         free(pairlist[i]);

                 free(pairlist);

                 free(postinput);

                 return postvars;

        }

 

 

5        参考

CGI编程完全手册(个人学习笔记)

http://wenku.baidu.com/view/11eb19f90242a8956bece4c2.html

 

apache的httpd.conf中文详解(转)

http://blog.linuxphp.org/archives/918/

 

让apache支持包含shtml,html,htm类型文件

http://www.woaidiannao.com/dnzs/17856.html

 

让apache支持包含shtml,html,htm类型文件(非原创)

http://www.myexception.cn/HTML-CSS/963539.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值