boa简介
BOA 服务器是一个小巧高效的web服务器,是一个运行于unix或linux下的,支持CGI的、适合于嵌入式系统的单任务的http服务器。
源代码开放、性能高。由于它是一个单任务的Web服务器,只能一次完成用户的请求,而不会fork出新的进程来处理并发的链接请求。但是Boa支持Cgi,能够为Cgi程序fork出一个进程来执行相应的客户请求。
Web服务器boa配置文件参数详细说明
boa的配置文件是**/etc/boa/boa.conf**。
Port:boa服务器监听的端口,默认的端口是80。如果端口小于1024,则必须是 root用户启动服务器。
Listen:绑定的ip地址。不使用这个参数时,将绑定所有的地址。
User:连接到服务器的客户端的身份,可以是用户名或UID。(为什么非要指定为文件的所有者才能访问网页呢?nobody用户也有读权限啊)
Group:连接到服务器的客户端的组,可以是组名或GID。
ServerAdmin:服务器出故障时要通知的邮箱地址。
ErrorLog:指定错误日志文件。如果路径没有以“/”开始,则相对于ServerRoot路径。没有配置时默认的文件是/dev/stderr。若不想记录日志,指定文件为/dev/null。
AccessLog:设置存取日志文件,与ErrorLog类似。
UseLocaltime:设置使用本地时间,使用UTC时注释这个参数。这个参数没有值。
VerboseCGILogs:在错误日志文件中记录CGI启动和停止时间,若不记录,注释这个参数。这个参数没有值。
ServerName:指定服务器的名称,当客户端使用gethostname + gethostbyname时返回给客户端。
VirtualHost:虚拟主机开关。使用此参数,则会在DocumentRoot设定的
目录添加一个ip地址作为新的DocumentRoot来
处理客户端的请求。如DocumentRoot设置为/var/www,则http://localhost/
则转换成/var/www/127.0.0.1/,若注释此参数,则为/var/www/。
DocumentRoot:HTML文件的根目录(也就是网站的目录)。
UserDir:指定用户目录。
DirectoryIndex:指定预生成目录信息的文件,注释此变量将使用DirectoryMaker变量。这个变量也就是设置默认主页的文件名。
DirectoryMaker:指定用于生成目录的程序,注释此变量将不允许列目录。
DirectoryCache:当DirectoryIndex文件不存在,而DirecotryMaker又被注释掉时,将列出这个参数指定目录给客户端。
KeepAliveMax:每个连接允许的请求数量。如果将此值设为" 0 ",将不限制请求的数目。
KeepAliveTimeOut:在关闭持久连接前等待下一个请求的秒数。(秒)。
MimeTypes:设置包含mimetypes信息的文件,一般是/etc/mime.types。
DefaultType:默认的mimetype类型,一般是text/html。
CGIPath:相当于给CGI程序使用的$PATH变量。
SinglePostLimit:一次POST允许最大的字节数,默认是1MB.
AddType: 增加MimeType没有指定的类型,例: AddType type extension [extension …]。要使用cgi,必须添加cgi类型:AddType application/x-httpd-cgi cgi
Redirect:重定向文件
Aliases:指定路径的别名。
ScriptAlias:指定脚本路径的虚拟路径。
交叉编译:
进入源码根目录,运行以下两条命令:
./configure
make CC=编译链(例如:arm-himix200-linux-gcc),如果是gcc,
则make CC就行。
交叉编译遇到的问题:
(1)修改compat.h:#define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
修改为:#define TIMEZONE_OFFSET(foo) foo->tm_gmtoff
(2)修改/src/boa.c,注释掉下面两行:
/if (setuid(0) != -1) {
DIE(“icky Linux kernel bug!”);
}/
*移植遇到的问题:
1、修改boa.conf配置文件,配置运行参数
(1)修改监听IP,在配置文件boa.conf中Listen 改为
Listen 0.0.0.0
注:设置监听ip为0.0.0.0 即主机IP。
(2)修改权限
将
User nobody
Group nogroup
改为
User 0
Group 0
(3)运行出错修改
#ErrorLog /var/log/boa/error_log改为
ErrorLog /var/log/boa/error_log
#AccessLog /var/log/boa/access_log改为
AccessLog /var/log/boa/access_log
ServerName www.your.org.here改为
#ServerName www.your.org.here
(4)网页文件路径设置
DocumentRoot /tmp
路径设置为/tmp 路径可以自主设置
(5)主页设置
DirectoryIndex login.html
主页设置为login.html,即登录显示这个网页的内容
(6)cgi的路径
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
/usr/lib/cgi-bin/为cgi的设置路径,可以自主设置
(7)boa.conf配置文件的路径设置
在defines.h中的#define SERVER_ROOT “/etc/boa”
其中"/etc/boa"为boa.conf配置文件的存放路径
2、日志调试配置
(1)在log.c中把以下代码屏蔽掉
/* if (fcntl(STDERR_FILENO, F_SETFD, 1) == -1) {
DIE(“unable to fcntl the error log”);
}*/
/* if (dup2(error_log, STDERR_FILENO) == -1) {
DIE(“unable to dup2 the error log”);
}/
(2) 在cgi.c中把以下代码屏蔽掉
/ if (!cgi_log_fd)
dup2(devnullfd, STDERR_FILENO);
else
dup2(cgi_log_fd, STDERR_FILENO);
*/
**注:**由于cgi把输入,输出、出错重定位,在cgi文件中无法使用stderr 、stdout输出调试信息,在终端无法使用printf打印调试信息。因为stdout被重定位,printf是用于向网页提交数据的。而stderr 被重定位于调试日志,如果不想使用日志调试,想在终端看调试信息,需要屏蔽stderr 的重定位效果,以上操作便是。除了终端调试,也可以通过printf进行网页调试,可以直接吧调试信息显示在网页上,或者通过fiddler来抓包看调试信息。
3、创建login.html,内容如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户登陆验证</title>
</head>
<body>
<form name="form1" action="/cgi-bin/login.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>
注:action="/cgi-bin/login.cgi"为cgi1的文件名
4、创建login.cgi文件
(1)login.c文件的内容如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
//printf("Content-type:text/html\n\n"); //这句一定要加上
fprintf(stdout, "Content-Type: text/html\r\n\r\n");
char name[128];
char passward[128];
char buf[128];
char *data;
int len,i,m,n;
char *method;
method = getenv("REQUEST_METHOD");
printf("method = %s\n",method);
memset(name , 0 , sizeof(name));
memset(passward , 0 , sizeof(passward));
fscanf(stdin, "Username=%[^&]&Password=%s",name,passward);
if(name[0] == '\0' || passward[0] == '\0')
printf("name or passward error!");
else
printf("name=%s passward=%s\n",name , passward );
fprintf(stderr, "passward = %s\n",passward);
fprintf(stderr, "name = %s\n",name);
len = atoi(getenv("CONTENT_LENGTH"));
fprintf(stderr, "len = %d\n",len);
fprintf(stdout, "$STATE$=1");
return 0;
}
注:stderr用于终端调试,stdout用于网页调试,或者交互。
(2)编译.c文件,生成cgi文件
gcc -o login.cgi login.c(如果是其他编译器,请用其他编译器的工具编译)
5、例子测试
(1)将配置文件boa.conf拷贝到/etc/boa中**
(2)将网页文件和cgi文件拷贝到对应的目录,上面路径的设置有提到,建议网页文件和cgi文件的路径设置一样,比如都在/tmp上
(3)运行./boa即可
(4)在网页上输入IP
比如:http://10.82.16.64/,显示主页网页的内容
输入用户名与密码,比如用户名:123 密码:123
则会调用CGI,执行对应cgi的内容
终端显示的他调试信息
以上为boa的cgi测试例子
接下来介绍boa的文件传输
1、参数配置:
(1)文件大小设置
在defines.h里
#define SINGLE_POST_LIMIT_DEFAULT 1024 * 1024 /* 1 MB */
其中1024 * 1024为文件的大小限制
(2)创建upload.html文件,内容如下:
<html>
<head>
<meta charset="utf-8"/>
<title>Upload</title>
</head>
<body>
<h2>File Upload to HTML</h2>
<form method="post" action="/cgi-bin/upload.cgi" enctype="multipart/form-data">
<table border="0">
<tr><td>File:</td><td><input type="file" name="file"></td></tr>
</table>
<input type="submit" value="send">
<input type="reset" value="cancel">
</form>
</body>
</html>
(3)创建upload.cgi文件
upload.c文件的部分内容如下:
int main(void)
{
fprintf(stdout, "Content-Type: text/html\r\n\r\n");
char name[128];
char passward[128];
char buf[512];
char *data;
int len,i,m,n;
char *method;
char *boundary,*boundarytemp;
int boundary_size = 0;
char filename[512]={0};
int length = 0;
UPDATE_TYPE_E update_type;
method = getenv("REQUEST_METHOD");
//UserLog_Debug_Local1_API("method = %s\n",method);
fprintf(stderr, "method = %s\n",method);
boundary = getenv("CONTENT_TYPE");
boundarytemp = strstr(boundary,"boundary=");
boundary_size = strlen(boundarytemp)-strlen("boundary=");
fprintf(stderr, "boundary_size = %d\n",boundary_size);
//UserLog_Debug_Local1_API("boundary_size = %d\n",boundary_size);
len = atoi(getenv("CONTENT_LENGTH"));
fprintf(stderr, "len = %d\n",len);
//UserLog_Debug_Local1_API("len = %d\n",len);
get_filetype_filename(filename);
fprintf(stderr, "filename =%s\n",filename);
//UserLog_Debug_Local1_API("update_type = %d filename =%s\n",update_type,filename);
length = save_tempfile(filename);
fprintf(stderr, "length = %d\n",length);
if(length == -1)
return -1;
truncate(filename,length-boundary_size-8);
fprintf(stdout, "upload ok!");
return 0;
}
(3)在网页上输入IP
http://10.82.16.64/upload.html
最后会在、tmp目录下有tempfile.txt 的文件生成。
测试例程代码:
链接:https://pan.baidu.com/s/19ijlrBkJJrP6TQMsMkxxWw
提取码:ixhv
测试例程步骤:
1、解压
tar -zxvf boa.tar.gz
2、打补丁
cd boa
patch -p1 < boa.patch
cd src
./configure
make
**3、**将****boa.conf拷贝到/etc/boa/
post和fileupload的文件拷贝到/tmp/下
4、./boa即可
注:在测试例程的upload.c文件里,需要把以下代码的注释去掉
把//close(STDIN_FILENO);改为close(STDIN_FILENO);
这样就会去掉文件上传时的文件备份,避免占用空间。