一.下载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
运行效果: