基础部分:
部署详细步骤如下
1.到http://www.boa.org/下载boa源码(下载得到boa-0.94.13.tar.gz),解压后得到boa-0.94.13文件夹。
2.运行./configure生成Makefile文件。
3.进入boa-0.94.13文件夹的src目录下,做如下修改:
(1)将defines.h中的 #define SERVER_ROOT "/etc/boa" 修改为 #define SERVER_ROOT "/boa"(这样boa程序启动时会在/boa目录下寻找boa.conf配置文件,并且将/boa文件夹作为服务器的根目录)。
(2)将boa.c中的
if(setuid(0) != -1)
{
DIE(”icky Linux kernel bug!”);
}
这三行注释掉,否则boa启动时会出现“boa.c:226 - icky Linux kernel bug!: No suchfile or directory错误”
(3)将compat.h中的 “#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff” 改为 “#define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff"
4.运行make
5.建立安装目录
mkdir -p /boa /boa/www /boa/cgi-bin /boa/log
6.将需要的文件复制到安装目录中
将boa-0.94.13/src目录下生成的boa、boa_indexer二进制文件复制到/boa下
将boa-0.04.13目录下的boa.conf文件复制到/boa下
将/etc/mime.types复制到/boa目录下
7.修改boa.conf配置文件,boa启动时会加载该文件。
按照如下格式修改(下面的文件去除了官方注释):
Port 80
User 0
Group 0
##### error_log和access_log会自动生成,只要指定生成路径就可以了。
ErrorLog /boa/log/error_log
AccessLog /boa/log/access_log
##### 存放HTML文件的根路径
DocumentRoot /boa/www
UserDir public_html
##### 默认页面,若之输入http://127.0.0.1/则会自动返回给浏览器默认页面index.html
DirectoryIndex index.html
##### 保持默认
DirectoryMaker /boa/boa_indexer
KeepAliveMax 1000
KeepAliveTimeout 10
MimeTypes /boa/mime.types
DefaultType text/plain
#####指定传给cgi程序的PATH环境变量
CGIPath /bin:/usr/bin:/usr/local/bin
#####保持默认
Alias /doc /usr/doc
#####如果输入http://127.0.0.1/cgi-bin/test.cgi, 则boa服务器会到/boa/cgi-bin中寻找test.cgi程序。
ScriptAlias /cgi-bin/ /boa/cgi-bin/
8.建立测试页面
(1)index.html,放在/boa/www目录下
<html>
<body>
<h3>this is a test!</h3><br/>
<img src="image.jpg"/>
<h3>tree picture</h3><br/>
<a href="/cgi-bin/test.cgi">to cgi page</a>
</body>
</html>
(2)test.c, 使用gcc -o test.cgi test.c编译后得到的test.cgi放在/boa/cgi-bin目录下
include <stdio.h>
int main()
{
printf("Content-type:text/html\n\n"); //这句一定要加上
printf("<html><body>");
printf("<font style=\"color:red; font-size:30px;\">Hello, CGI!</font><br/>");
printf("<a href=\"/index.html\">return index.html</a>");
printf("</body></html>");
return 0;
}
~
9.测试效果
进入/boa目录,使用./boa来运行boa服务器(当然也可将/boa路径加入系统PATH环境变量,这样不用进入/boa目录,直接输入boa就可以了)
在浏览器中输入http://127.0.0.1/便可访问到默认的页面index.html, 点击index.html页面中的超链接便可访问到cgi测试页面,点击test.cgi中的超链接又可返回index.html页面。
(1)index.html页面
(2)test.cgi页面
以上是在PC上部署BOA的大致步骤,仅供参考。
扩展部分:
下面是一个使用html + cig 模仿用户登录的一个例子的源码,感谢原作者的分享。
功能:在pass.html中输入用户名和密码,提交到pass.cgi程序中并将账户和密码打印出来。
pass.html页面:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户登陆验证</title>
</head>
<body>
<form name="form1" action="/cgi-bin/pass.cgi" method="POST">
<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>
</html>
pass.cgi的源码pass.c:
#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;
}
补充说明:
(1)移植boa到嵌入式linux上的方法和上面几乎一样,具体做法是在./configure生成Makefile后将Makefile中的CC = gcc 改为CC = arm-linux-gcc,将CPP=gcc -E 改为 CPP = arm-linux-gcc -E,然后make就可以了。
(2)移植boa到嵌入式linux后,在启动时若出现“gethostbyname:: Success"然后程序退出,则需在原boa.conf文件中增加一行:
ServerName www.your.org.here
然后重新运行boa就可以了。需要注意,若系统中有多个boa程序,则不应该将boa加入PATH环境变量中,这样相互之间干扰可能引起异常,而应该使用带路径的方式来启动boa程序。