嵌入式WEB服务器搭建-lighttpd+cgi
文章目录
1. 基本介绍
Lighttpd 是众多开源的轻量级 Web Server 中较为优秀的一个,支持 FastCGI、CGI、Auth、输出压缩(output compress)、URL 重写、Alias 等重要功能,具有非常低的内存开销,CPU 占用率低,效能好,且ighttpd易配置https,实现安全访问页面功能。
Lighttpd一般用在嵌入式设备中,嵌入式设备的磁盘空间和内存相对有限,主要还是运行设备的主程序,预留给Web服务器的资源相对较少,因此在嵌入式设备中不可能部署大型的Web服务器,比如使用tomcat等,所以在嵌入式设备中轻量级的Lighttpd是个很好的选择。
2. Lighttpd 移植
2.1 源码下载
https://www.lighttpd.net/2023/2/10/1.4.69/
2.2 源码编译
./configure --host=arm-linux target=arm-linux --disable-FEATURE --enable-shared --disable-static --disable-lfs --disable-ipv6 --without-PACKAGE --without-valgrind --without-openssl --without-kerberos5 --with-pcre --without-zlib --without-bzip2 --without-lua
make && make intall
3. CGI介绍
通用网关接口(Common Gateway Interface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。
服务器和客户端之间的通信,是客户端的浏览器和服务器端的http服务器之间的HTTP通信,我们只需要知道浏览器请求执行服务器上哪个CGI程序就可以了,其他不必深究细节,因为这些过程不需要程序员去操作。
服务器和CGI程序之间的通讯才是我们关注的。一般情况下,服务器和CGI程序之间是通过标准输入输出来进行数据传递的,而这个过程需要环境变量的协作方可实现。
4. 环境变量
CGI环境变量名称 | 说明 |
---|---|
REQUEST_METHOD | 请求类型,如“GET”或“POST” |
CONTENT_TYPE | 被发送数据的类型 |
CONTENT_LENGTH | 客户端向标准输入设备发送的数据长度,单位为字节 |
QUERY_STRING | 查询参数,如“id=10010&sn=liigo” |
SCRIPT_NAME | CGI脚本程序名称 |
PATH_INFO | CGI脚本程序附加路径 |
PATH_TRANSLATED | PATH_INFO对应的绝对路径 |
REMOTE_ADDR | 发送此次请求的主机IP |
REMOTE_HOST | 发送此次请求的主机名 |
REMOTE_USER | 已被验证合法的用户名 |
REMOTE_IDENT | WEB服务器的登录用户名 |
AUTH_TYPE | 验证类型 |
GATEWAY_INTERFACE | 服务器遵守的CGI版本,如:CGI/1.1 |
SERVER_NAME | 服务器主机名、域名或IP |
SERVER_PORT | 服务器端口号 |
SERVER_PROTOCOL | 服务器协议,如:HTTP/1.1 |
DOCUMENT_ROOT | 文档根目录 |
SERVER_SOFTWARE | 服务器软件的描述文本 |
HTTP_ACCEPT | 客户端可以接收的MIME类型,以逗号分隔 |
HTTP_USER_AGENT | 发送此次请求的web浏览器 |
HTTP_REFERER | 调用此脚本程序的文档 |
HTTP_COOKIE | 获取COOKIE键值对,多项之间以分号分隔,如:key1=value1;key2=value2 |
备注:
- C程序中通过getenv接口获取环境变量值。
- 如果REQUEST_METHOD是GET直接从QUERY_STRING中获取参数,如果REQUEST_METHOD是POST从stdin中读取CONTENT_LENGTH长度的数据。
- POST与GET的区别如下,以 GET 方式接收的数据是有长度限制,而用 POST 方式接收的数据是没有长度限制的。并且,以 GET 方式发送数据,可以通过URL 的形式来发送,但 POST方式发送的数据必须要通过 form 才到发送。
5. CGI执行
- 服务器将URL指向一个应用程序
- 服务器为应用程序执行做准备
- 应用程序执行,读取标准输入和有关环境变量
- 应用程序进行标准输出
6. 配置文件
server.modules += (
"mod_alias",
"mod_cgi"
)
server.document-root = "/www"
server.pid-file = "/tmp/run/lighttpd.pid"
server.port = 8090
server.stream-request-body = 2
server.breakagelog = "/tmp/web_cgi.log"
index-file.names = ("index.html")
cgi.assign = (".cgi" => "")
alias.url = ( "/cgi-bin/" => "/var/www/cgi-bin/" )
include "/etc/lighttpd/mime.conf"
备注:红色字体表示启用cgi,如不开启cgi功能,在访问cgi文件时就不会调用cgi程序,而是把cgi文件下载下来。
7. 进程启动
/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf
8. 测试实例
- 实现页面上输入的两个数乘积,通过后台CGI计算,并返回到页面。
8.1 前端页面获取
<html>
<body>
<meta charset="utf-8">
<form ACTION="/cgi-bin/mult.cgi">
<P>计算两个数的乘积,请输入两个乘数。
<INPUT NAME="m" SIZE="5">
<INPUT NAME="n" SIZE="5"><BR>
<INPUT TYPE="SUBMIT" values="提交">
</form>
</body>
</html>
在浏览器上访问
http://192.168.58.128:8090/index.html
8.2 后端CGI处理
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *data, *cgi, *mtd, *addr;
long m, n;
printf("%s\n\n","Content-Type:text/html;charset=utf-8");
cgi = getenv("SCRIPT_NAME");
printf("<P>CGI路径:%s", cgi ? cgi : "invaild path");
mtd = getenv("REQUEST_METHOD");
printf("<P>请求方式:%s", mtd ? mtd : "invaild request method");
addr = getenv("REMOTE_ADDR");
printf("<P>请求主机:%s", addr ? addr : "invaild host");
printf("<TITLE>乘法结果</TITLE> ");
printf("<H3>乘法结果</H3> ");
data = getenv("QUERY_STRING");
if (data == NULL)
printf("<P>错误!数据没有被输入或者数据传输有问题");
else if (sscanf(data, "m=%ld&n=%ld",&m, &n)!=2)
printf("<P>错误!输入数据非法。表单中输入的必须是数字");
else
printf("<P>%ld和%ld的乘积是:%ld", m, n, m*n);
return 0;
}
在浏览器上访问
9. 参考资料
https://blog.csdn.net/maikforever/article/details/7738798
https://www.cnblogs.com/wanghetao/p/3934350.html