嵌入式web服务器的选择

cgi

作为一个web服务器,仅仅是提供静态的网页内容肯定是不够的。对于嵌入式来说,基本上是通过cgi来扩展web服务器,用来提供内容。web服务器会监测到用户在浏览器中的一些动作,通常是POST,GET(对应用户的操作就是刷新、点击提交等动作),这些动作会绑定到某个cgi程序来处理。

传统用C做CGI的方法是直接使用printf() 等标准I/O函数输出HTML代码。

CGI是一种提供动态生成网页的概念,除了传统的用C来实现,也有其它的类似的技术。其中有一种JSP的技术,Servlet是Java技术对CGI编程的回答。Servlet程序在服务器端运行,动态地生成Web页面。与传统的CGI和许多其他类似CGI的技术相比,Servlet具有更高的效率,更容易使用,功能更强大,具有更好的可移植性,更节省投资。JSP是强于CGI,这也是现在CGI技术的使用没有JSP使用多的原因。但现在嵌入式web服务器端程序开发,还是CGI较多。由于使用JSP技术,在嵌入式web服务器开发中很少使用,在网上没有查到关于在嵌入式web服务器上应用的有关内容。

综合比较了thttpd,boa,goahead等适用于嵌入式设备上的web服务器,最终还是选择了goahead,因为它的功能功能强大,支持javascript,asp。不像其它的,只支持cgi。

考虑到使用范围宽广程度,在小型服务器、不要求太强功能,推荐选用boa、thttpd,其实它们足可以满足大多数情况下的需求,也是使用最广、可参考最多的嵌入式web服务器。如果要求强大的功能,支持javastript等,推荐选用goahead、appweb。

CGI相关概念:
https://www.jianshu.com/p/c4dc22699a42
https://zhuanlan.zhihu.com/p/25013398
https://blog.csdn.net/weixin_39609623/article/details/86312439

编译

修改源码,因为是嵌入式设备使用,通常设备可能并没有连接到公网。无法解析hostname得到ip地址。需要修改src/http.c 文件中的源码,修改的地方参考网上的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#if 0
struct hostent *hp;
if ((hp = gethostbyname(host)) == NULL) {
error("Cannot get host address for host %s: errno %d", host, errno);
return -1;
}
memcpy((char*) &intaddr, (char *) hp->h_addr_list[0], (size_t) hp->h_length);
ipaddr = inet_ntoa(intaddr);
#else
/* new add */
int sockfd;
struct sockaddr_in sin;
struct ifreq ifr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1)
{
error("get socket error!\n");
return -1;
}
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1]=0;
if(ioctl(sockfd, SIOCGIFADDR, &ifr)<0)
{
error("ioctl error!\n");
return -1;
}
memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
ipaddr = inet_ntoa(sin.sin_addr);
#endif

上面 被注释掉的部分就是修改前的,#else部分就是修改后的。

修改完后,交叉编译主要指定CC和ARCH两个变量。使用如下的命令来交叉编译:

1
2
source /opt/arm49/env.sh
make

交叉编译之后,在build/linux-arm-default/bin目录有生成的相关文件。

也可以不修改源码,编译完毕,部署到设备之后,运行会提示无法解析myimx6ek314这个hostnamne。只需要修改/etc/hosts,添加一条解析myimx6ek314到127.0.0.1的记录即可。

部署

生成的bin目录下的文件有:
ca.crt ec.crt goahead gopass libgoahead-mbedtls.a roots.crt self.key test.key
ca.key ec.key goahead-test libgo.so libmbedtls.a self.crt test.crt

  1. goahead、goahead-test、gopass放到设备的/usr/bin/目录下。

  2. libgoahead-mbedtls.a ibmbedtls.a 文件可以删除。

  3. 其它文件拷贝到 /etc/goahead 目录下。

  4. 另外将src/route.txt src/auth.txt 拷贝到 /etc/goahead 目录下。

  5. 创建目录/var/www 作为存放网页资源的目录。创建一个index.html 页面放入/var/www作为测试用。

运行

使用如下的命令来运行goahead

1
goahead  -v --home /etc/goahead /var/www 0.0.0.0:80

参考资料

https://www.embedthis.com/goahead/doc/start/running.html
https://www.embedthis.com/makeme/doc/source/make.html
https://www.embedthis.com/goahead/doc/users/