boa(web服务器)之交叉编译、移植、cgi、文件上传篇

2023-11-18

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);
这样就会去掉文件上传时的文件备份,避免占用空间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boa(web服务器)之交叉编译、移植、cgi、文件上传篇 的相关文章

  • 期待、互动,然后再次期待

    有几篇关于相同内容的帖子 但我仍然无法使我的期望脚本正常工作 我的目的是自动化一切 但保留用户输入的密码 所以脚本有 3 个部分 自动登录 给予用户交互以输入密码 将控制权交还给 Expect 脚本以继续工作 所以我有一个将生成的脚本 其中
  • Linux Shellcode“你好,世界!”

    我有以下可用的 NASM 代码 global start section text start mov eax 0x4 mov ebx 0x1 mov ecx message mov edx 0xF int 0x80 mov eax 0x1
  • 为什么“script”命令会生成 ^[ 和 ^M 字符以及如何使用 vim 搜索和替换删除它们?

    在linux上 使用bash shell 当我使用script命令时 生成的文件称为typescript 当我用 vim 打开该文件时 每一行都包含 M字符 并且有几行 由于我的彩色命令提示符 包含一个字符 我想用任何东西替换这些字符 从而
  • 有没有办法只安装mysql客户端(Linux)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有不需要安装整个mysql db安装包的Linux mysql命令行工具 我想做的是从服务器 1 应用程序服务器 执行将在服务器 2
  • VSCODE 在 Linux 上不适用于我

    刚刚了解 VSCODE 很高兴尝试一下 我下载 解压并运行可执行文件 我得到 Code 2183 0429 201254 ERROR browser main loop cc 170 Running without the SUID san
  • SVN 不断提示我输入密码并拒绝缓存我的凭据

    环境 Eclipse Indigo Ubuntu 11 04 Subclipse 1 6 SVN 客户端 Subclipse RabbitVCS 我通过 svn ssh 连接 我的网址如下所示 svn ssh 我的名字 我的域名 路径 我可
  • X 服务器使用什么像素格式?

    X 服务器使用什么像素格式 RGBA ARBG BGRA 如果有任何特定格式的话 Update 我专门寻找有关颜色分量顺序和位模式的信息 你的意思是帧缓冲区格式 或者所有支持的像素图格式 无论是哪一种 都取决于您的图形硬件 驱动程序和配置
  • OS X 对 /usr/local/lib 的权限被拒绝

    我正在寻找有关权限问题的任何建议 直觉 线索 答案 自从我切换到新的 Macbook Pro 以来 这个问题一直困扰着我 这就是困境 某些程序在安装期间复制 usr local lib 下的库 并且在运行这些程序时出现崩溃 我认为这与此文件
  • 如何在 Linux 中显示进程状态(阻塞、非阻塞)

    有没有办法查询 Linux 进程表中进程的状态 以便能够演示执行查询时进程是正在运行还是被阻止 我的目标是从进程或程序的 外部 执行此操作 因为我希望从操作系统进程的角度来理解这一点 但欢迎任何想法 这是Python代码阻塞的过程 impo
  • 如何在树莓派上更新到最新的 python 3.5.1 版本?

    我昨天拿到了 Raspberry Pi 我已经在尝试用它来编写代码了 我有一个计划在其上运行的程序 但它仅与 Python 版本 3 5 0 或 3 5 1 兼容 并且我在互联网上找到的所有内容似乎都已经过时 与 Python 2 有关 或
  • 如何获取文件夹的大小,包括稀疏文件的表观大小? (du太慢了)

    我有一个包含很多KVM qcow2文件的文件夹 它们都是稀疏文件 现在我需要获取文件夹的总大小 qcow2 文件大小应计为表观大小 而不是实际大小 例如 图片 c9f38caf104b4d338cc1bbdd640dca89 qcow2 文
  • 并发 I/O - 缓冲区损坏、块设备驱动程序

    我开发块分层设备驱动程序 所以 我拦截WRITE请求并加密数据 并解密数据end bio 例行程序 在处理和READ要求 所以在单流中一切正常 但是 如果尝试同时从两个或更多进程执行 I O 我会遇到缓冲区内容损坏的情况 我没有任何本地存储
  • gnutls_handshake() 失败:握手失败 GIT

    一切都工作正常 但突然我收到错误 致命 无法访问 https 电子邮件受保护 cdn cgi l email protection name repo name git gnutls handshake 失败 握手失败 我在我的计算机和 E
  • 使用 xargs 时如何获取退出代码(并行)

    我制作了一个用于启动并行 rsync 进程的脚本 bin bash LIST 1 DEST DIR 2 RSYNC OPTS 3 echo rsyncing From SRC DIR To DEST DIR RSYNC OPTS RSYNC
  • 在Linux中执行jar文件[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我创建了一个可执行的 Java jar 文件 也就是说 我将 java 程序正确打包到 jar 文件中 包括 META INF MANIFEST 文件
  • Bash 脚本错误 [重复]

    这个问题在这里已经有答案了 我想知道下面的脚本有什么错误 我收到错误为 command not foundh line 1 command not foundh line 2 其连续的 我试过添加 但现在工作请告诉我该怎么做 bin bas
  • 导出多个 LD_LIBRARY_PATH 的正确方法

    对于linux的使用 我是一个新手 根据有关我的项目的指南 我必须多次导出 LD LIBRARY PATH 并且我不确定是否不覆盖它们 Cupti Tensorflow CUDAit export LD LIBRARY PATH LD LI
  • 如何像C99一样使用make和编译?

    我正在尝试使用 Makefile 编译 Linux 内核模块 obj m main o all make C lib modules shell uname r build M PWD modules clean make C lib mo
  • tcmalloc/jemalloc 和内存池之间有什么区别(以及选择的理由)?

    tcmalloc jemalloc是改进的内存分配器 还引入了内存池以更好地分配内存 那么它们之间有什么区别以及在我的应用中如何选择它们呢 这取决于您的程序的要求 如果您的程序有更多的动态内存分配 那么您 需要从可用的分配器中选择一个内存分
  • Docker容器内的动态监听端口

    我有一个应用程序 在使用其默认端口建立一些连接后 开始打开 侦听 新的随机端口来处理现有连接 然后删除它们 视频通话 它还在通信协议内交换其IP地址和端口 我能够解决IP地址问题 但仍然无法找到一种方法来动态告诉主机的IPTABLES在Do

随机推荐

  • 自己编写DLL文件——注册——VB工程引用——标准EXE调用(含例子)

    VB6 0的 工程 引用 中有很多控件供用户使用 但有时需要自己编写dll文件以实现某些功能 本文介绍如何自己编写一个简单的dll文件 然后在win7 64位下使用regsvr32注册 并在VB6 0中引用 最后在标准EXE中调用实现某些功
  • ES 版本,及重要特性

    参考 https www cnblogs com flyrock ES release 地址 https www elastic co cn downloads past releases elasticsearch ES版本 发布日期 版
  • 熊啸锋:精准营销及推广的四个步骤,倍增你的利润

    哈喽 我是熊啸锋老师 今天分享的主题是精准营销及推广的四个步骤 作为营销人 企业老板 项目负责人 市场开发人员等 你会经常面临 如何开发客户 如何获得大量的潜在客户名单 等很多的问题 还经常有人抱怨说 我们获取的潜在客户名单不精准 成交率非
  • Linux中清空文件的方法

    Linux中清空文件的方法 平时工作过程中 经常会遇到需要清空linux中某个日志文件的方法 下面总结一下几个常用的方法 以下待清空的文件名统一使用 test txt 表示 方法1 vi 中使用 d 1 输入 vi test txt 回车
  • word添加gif

    word添加gif动图最简单的方法 无需链接无需插件 X to Y的博客 CSDN博客 word插入动图 原文链接 https blog csdn net X To Y article details 124415532 文章目录 word
  • c++ Graphics 实现俄罗斯方块

    俄罗斯方块 一 游戏规则 1 方块种类 2 操作规则 玩家可以通过 按键 功能 a 向左一格 d 向右一格 s 顺时针旋转90度 w 逆时针旋转90度 3 积分规则 玩家根据消除的行列数量获取得分 数量 得分 1行 10分 2行 30分 3
  • Vue中的import中@的作用

    这是webpack的路径别名 相关代码定义在配置文件webpack base config里 resolve 自动补全的扩展名 extensions js vue json 默认路径代理 例如 import Vue from vue 会自动
  • UVA-10603 倒水问题 题解答案代码 算法竞赛入门经典第二版

    GitHub jzplp aoapc UVA Answer 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 使用广度优先搜索和优先队列 如果找到最小的点则退出 找不到就遍历所有的情况 include
  • 在vue中引入高德地图

    既然要用到高德地图首先要申请成为高德地图开发者 并申请使用高德地图的key这两点在这篇文章就不过多赘述 有需要的小伙伴可以查查资料 或者去高德地图api官网都有很详细的介绍 高德地图官网 简单提一下申请秘钥流程 web端 控制台 gt 应用
  • Android中的关于MDM中的几个方法举例

    首先介绍一下MDM是什么的缩写 MDM是什么 MDM 是 Mobile Device Management 的缩写 中文翻译过来就是移动设备管理 随着移动设备计算能力地增强 移动设备携带越来越方便 移动化办公已经成为一种潮流 一种趋势 企业
  • MATLAB_第二篇神经网络学习_BP神经网络

    非常感谢博主wishes61的分享 这篇博客只是为了记录下第一个神经网络的训练 BP神经网络代码实现 1 BP神经网络的简介和结构参数 1 1 BP神经网络的结构组成 1 2 神经元结构示意图 1 3 BP神经网络训练界面的参数解读 2 B
  • 【华为OD机试】战场索敌(C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 题目描述 有一个大小是N M的战场地图 被墙壁 分隔成大小不同的区域 上下左右四个方向相邻的空地 属于
  • 蓝牙协议规范--L2CAP

    L2CAP 分析 记住一点 软件和硬件分开理解 数据经由物理通道交互 上层通道由各层协议打通 L2CAP 全称为逻辑链路控制与适配协议 Logical Link Control and Adaptation Protocol 位于基带层之上
  • 聚簇索引与非聚簇索引(也叫二级索引)

    索引 索引 是 存储引擎 用于快速找到记录的一种 数据结构 MYSQL中索引在存储引擎层实现 而非服务器层 索引类型 聚簇索引 非聚簇索引 二级索引 主键索引 辅助索引 复合索引 前缀索引 唯一索引 压缩索引 全文索引 Hash索引 列索引
  • Redis学习笔记2:了解 Redis 入门

    1 Redis是什么 Remote Dictionary Server 远程字典服务 Redis是现在最受欢迎的NoSQL数据库之一 Redis是一个使用ANSI C编写的开源 包含多种数据结构 支持网络 基于内存 可选持久性的键值对存储数
  • 如何的pycharm远程连接服务器Ftp

    话不多说 我们直接开始上图操作 以上就是整体的配置过程
  • ElasticSearch入门

    文章目录 一 ElasticSearch简介 1 什么是ElasticSearch 2 ElasticSearch使用案例 3 ElasticSearch对 Solr 二 ElasticSearch相关概念 术语 1 概述 2 索引 ind
  • MyBatis学习(二):解析MyBatis配置文件的写法和使用原理

    MyBatis学习 一 一个简单的演示 上面就是一个很简单的MyBatis的应用实例 可以看看 对于如何如此做可能就不是很清楚了 首先每一个MyBatis的应用程序都是以一个SqlSessionFactory对象的实例为核心 SqlSess
  • excel在双显示器上打开两个独立的xlsx表格

    平时配置的双显示器 要在两个显示器上各打开一个excel表格 一个用来做参考 另一个用来制作新表格 默认的office竟然不支持同时开两个独立窗口的excel表格 解决方式是安装微软的新补丁 http download microsoft
  • boa(web服务器)之交叉编译、移植、cgi、文件上传篇

    boa简介 BOA 服务器是一个小巧高效的web服务器 是一个运行于unix或linux下的 支持CGI的 适合于嵌入式系统的单任务的http服务器 源代码开放 性能高 由于它是一个单任务的Web服务器 只能一次完成用户的请求 而不会for