当前位置:
文档之家› 嵌入式Web服务器的设计及其CGI实现
嵌入式Web服务器的设计及其CGI实现
0引言
在嵌入式设备中加入 HTTP 服务能将其转化成 Web Server,可以向 Internet 或内部网提供基于 Web 的图形化管理接 口 。 用 户 可 以 使 用 浏 览 器 作 为 接 口 来 访 问 嵌 入 式 设 备 ,这 样 不仅能使嵌入式设备的易用性大大提高,而且方便统一管理。
1.2 软 件 架 构 本文提出的嵌入式 Web 服务器软件结构如图 1 所示,主
要功能模块说明如下: (1)Socket 层:HTTP 建立在运输层 TCP 之上,嵌入式 Web
服务器则建立在安全套接口之上; (2)HTTP/XML 解析:HTTP 请求报文分析模块,分析 HTTP
报文头部,支持 HTTPv1.1 版本、支持请求方法 GET 和 POST、 支持认证、支持 CGI。如果 HTTP Parser 发现 HTTP 报文中的 有 XML 消息,那么 HTTP Parser 将把这个报文交由 XML Parser 来处理;
结 合 嵌 入 式 系 统 的 应 用 ,考 虑 到 我 们 没 有 必 要 处 理 大 量 的客 户请 求,也 没有 必要 去一 味追 求并 行处 理速 度,我 们需 要的 是设 计一 个基 于 Web 的管 理模 块 ,所以 减小 应用 程序 大小非常关键。本文中减小应用程序大小的具体作法是把 传统的 CGI 应用程序 和嵌入式 Web 服务器 模块整合在一起 , 这样就能从根本上减小应用程序长度。在具体实现中是把 每个传统的 CGI 应用程序中的主函数(一般是 main 函数)都 转为 嵌入 式 Web 服务 器内 部的 一个 回 调函 数,并 由嵌 入式 Web 服 务器 在分 析 HTTP 请 求之 后,负责 回调 CGI 函 数。如 图 3 所示。
Abstract:The resource of embedded device is limited, and the capacity of RAM and ROM is very small, so it is difficult to implement the web server function under the resource limited situation. Based on the analysis of HTTP1.1, the features of the embedded web server and its designing idea are given, and simplified software architecture for embedded web server is also introduced. The implement strategy of CGI for embedded web server is described in detail. Finally, the HTTP connection is successfully achieved with C language program. Key words:embedded system; web server; CGI; HTTP; callback function
多任务 CGI 实现方法的好处是有较大的吞吐量,能并行
CGIs
CGI
Application 1
CGI Application 2
……Biblioteka CGI Application n
stdin, stdout fork and pipe stdin, stdout stdin, stdout
HTTPD Send response
- 1598 -
Send response Callback CGI funotions Parse Script Code
CGI functions/ XML generators
Server Script Engine
Read Read
CGI Environments
Create HTTP/XML Parser
Design of embedded web server and its implementation of CGI
XIE Shi-yi, XU Bing (College of Information, Guangdong Ocean University, Zhanjiang 524088, China)
多任务环境下 CGI 实现主要通过多任务守护进程 HTTPD (如: Apache,uClinux-httpd 等) 来完成。HTTPD 首先接受分析 Web 浏览器的 HTTP 请求,然后 fork() 一个子进程去处理这个 请求。在刚 fork()出来的子进程中,将根据 URL 去调用相应的 CGI 程序。 在用子进程调用 CGI 程序之前,先创建子进程与 CGI 应用程序相互通信的输入输出管道和 CGI 环境,关闭 CGI 应 用 程 序 的 标 准 输 入 输 出 。并 把 刚 创 建 的 输 入 输 出 管 道 描 述 字转换到标准输入输出描述字,然后向 CGI 应用程序的输入 管道传送请求,这样 CGI 就能像操作标准输入输出那样读写 管道了。
嵌入式 Web 服务器是实现嵌入式系统通过 Web 方式与 Internet 互联的关键组成部分,而 CGI 是用户与 Web 服务器交 互的一个重要途径。本文将重点讨论嵌入式 Web 服务器中 CGI 的实现策略,并给出实现 CGI 的主要接口和调用代码。
2 嵌入式 Web 服务器中 CGI 实现策略
处 理 多 个 请 求 。 但 这 种 作 法 也 有 它 的 不 利 之 处 :① 系 统 开 销 大,Fork() 的调用势必造成系统开销大,特别是在嵌入式系统 中,这种开销还带来很多不稳定的因素;②由于 CGI 应用程序 是独立于嵌入式 Web 服务器的,而且 CGI 应用程序之间也是 相互独立的,这样在一些不支持 MMU(内存管理单元)的平台 下,每个 CGI 应用程序都使用静态连接库,这样 CGI 的大小将 大得很难控制。 2.2 回 调 CGI 函 数
(3)CGI 环境变量(CGI Environment):操作系统提供了许多 环 境 变 量 ,它 们 定 义 了 程 序 的 执 行 环 境 ,应 用 程 序 可 以 存 取 它 们。嵌入式 Web 服务器和 CGI 接口又另外设置了自己的一些 环境变量,用来向 CGI 程序传递一些重要的参数。CGI 的 GET 方法还通过环境变量 Query-String 向 CGI 程序传递 Form 中的 数据。但我们这里的 CGI Environments 不是真正的环境变量, 嵌入式 Web 服务器仅仅是模拟环境变量向 CGI 传递一些重要 的信息,它是由 HTTP Parser 模块创建,所有 CGI 函数和脚本引 擎 模 块 将 读 此 环 境 变 量 ,并 根 据 这 些 变 量 做 出 相 对 应 的 操 作 ;
3.1 CGI 环 境 变 量 CGI 环境变量是 CGI 的重要组成部分之一,嵌入式 Web
服务器和 CGI 接口都设置了自己的一些环境变量,用来向 CGI 程序传递一些重要的参数。CGI 环境变量是由图 1 中的 HTTP 解析模块创建,所有 CGI 函数和脚本引擎模块将读此环境变 量,并根据这些变量做出相对应的操作。在图 1 中 CGI Environment 模块需要定义一些全局变量作为环境变量,其定义和 注释如下:
……
HTTP Parser Socket
fork and parse
图 2 CGI 应用架构
Callback Callback Callback
CGI Function 1
CGI Function 2 …… CGI Function n ……
HTTP parser
图 3 回调 CGI 函数
3 CGI 实现
File System
HTML paees CSSs JPGs BPMs JSs XMLs
etc
Send response Parse Http request Socket Layer/Secure Socket Layer
HTTPD
图 1 软件架构
的好处是:对于整个 Web 模块来说,可执行文件的长度大大减 小,执行速度大大提高,但这是以牺牲移植性和独立性为代价的。
extern char *cgiServerSoftware; /* Web server software */ extern char *cgiServerName; /* Web server software name */ extern char *cgiGatewayInterface; /* Gateway interface */ extern char *cgiServerProtocol; /* The protocol server used */ extern int cgiServerPort; /* The port server used */ extern char *cgiRequestMethod;/* Request method of client */ extern char *cgiPathInfo; /* CGI Script path information */ extern char *cgiPathTranslated; /* Path translated */ extern char *cgiScriptName; /* CGI script Name */ extern char *cgiQueryString; /* Query string from client */ extern char *cgiRemoteHost; /* client host */ extern char *cgiRemoteAddr; /* client address */ extern char *cgiAuthType; /* Authentication type */ extern char *cgiRemoteUsrer; /* Authentication user */ extern char *cgiRemoteIdent; /* Client Identity */