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