一.下载boa源码并解压
官网网站:BOA源码
点击箭头所指的位置即可下载
解压:
tar -xvf boa-0.94.13.tar.gz
解压完成得到目录:
二.安装环境所缺依赖,否则编译会报错
sudo apt install bison
sudo apt install flex
三.编译
1.生成Makefile
/boa-0.94.13/src$ ./configure
2.在src,执行make
and@and-VirtualBox:~/linux网络编程/boa/boa-0.94.13/src$ make
bison -y -d boa_grammar.y
gcc -g -O2 -pipe -Wall -I. -c -o y.tab.o y.tab.c
y.tab.c: In function ‘yyparse’:
y.tab.c:1191:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
yychar = yylex ();
会编译报错:
解决:
在src/compat.h文件120行
#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
改为#define TIMEZONE_OFFSET(foo) foo->tm_gmtoff
编译完成会在src下面生成可执行文件boa
运行boa,出现报错
解决:创建/etc/boa目录
关于该目录的定义在 defines.h中。
继续运行,又报错
解决:
拷贝boa-0.94.13/boa.conf文件到/etc/boa目录下。
继续运行,又报错
注释掉:在src/log.c 72-74行
if (dup2(error_log, STDERR_FILENO) == -1) {
DIE("unable to dup2 the error log");
}
又一个报错
解决:
AccessLog /var/log/boa/access_log
改为
#AccessLog /var/log/boa/access_log
发现改了也不行,后面把boa.conf cp到了etc/boa/下面进行了替换就OK了
修改url路劲
当前编译环境OK,需要修改boa.conf文件,因为我们输入url的时候,会在对应的路劲下面去找,如果路劲不对,就会找不到,页面出现404
在我的虚拟机下面,我放了如下文件
在boa.conf做如下修改
111行
DocumentRoot /home/and/www
最后一行
ScriptAlias /cgi-bin/ /home/and/www/cgi-bin/
其中/cgi-bin/指的就是当我们访问的文件带有cgi-bin字段的时候,就表示动态网页信息,因此我们的服务器,就会从后面的路劲/home/and/www/cgi-bin/下面去寻找此文件。
注意:这里的路劲使用绝对路径,否则出现找不到的情况。还有/cgi-bin/最后面的/一定不能缺少,不然还是找不到。
四.运行效果:
看一下进程运行情况
ps -a | grep "boa"
在index.html
<html>
<head>
<title>table</title>
<meta charset="UTF-8">
</head>
<body>
选择你的车型:
<select>
<option>BMW</option>
<option>玛莎拉蒂</option>
<option>火车</option>
<option selected>宝骏</option>
<option>自行车</option>
</select>
</body>
</html>
效果如下:
在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.c输入如下:
/*=====================================================================
cgi例子
=====================================================================*/
//pass.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getcgidata(FILE* fp, char* requestmethod);
int main(void)
{
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;
}
编译为pass.cgi
编译 gcc pass.c -o pass.cgi 并赋予权限,一般我都是直接拉满 chnod 777 pass.cgi
运行效果: