Mongoose(SHTTP)+LUA

本文介绍了一款自研的支持Lua脚本的嵌入式Web服务器,该服务器旨在与多种Web服务器集成,而非独立运行。文章详细阐述了开发背景、基本思路及代码结构,并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前端时间需要一个嵌入式的webserver,但最终没有一个比较满意的。

最近就在想是否自己写一个支持lua脚本的服务器版本,可以嵌入到各种webserver中,且是与webserver集成在一起,而非单独进程方式(类似cgi)。

想到那么就开始动手写,由于之前利用的是cgilua,那么就做一个cgilua的子集吧,尽量兼容。

需求

  1. 兼容cgilua,其网页格式仍然以.lp为后缀
  2. lp文件格式通cgilua
  3. 尽量做到少依赖其他库或者文件(比如说SAPI,expact等)
  4. 文件尽量少,可以方便的在linux,windows,uclinux,vxworks下移植和使用
  5. 不创建新的进程/Task来处理lp
  6. 暂不支持sajax

基本思路

  1. 读取lp文件,并解释成LUA语法。将HTML语句转换cgilua.put语句,去掉LUA语句前后的转义字符
  2. 调用LUA虚拟机执行lua语句,将结果通过webserver发送出去
  3. webserver在适配代码中需要将POST信息,环境变量等信息传递给lua虚拟机,传递方式就是创建相应的POST和env数组

代码结构

代码主要分为两部分,一部分为实现lp文件解析,另一部分为与webserver之间的适配代码。

  • sluacgi.c、lua.c为lp解析文件
  • mongoose.c为webserver代码和适配代码(可与mongoose源码比较,新增代码为适配代码)
  • main.c

选择mongoose的缘故是因为mongoose可以在windows下运行,方便调试

 

接口

对外接口

  • lp_load: 加载文件,并解释成lua语法。对应与lp_load_free,释放lp_load所申请的资源
  • lp_parse:启动LUA虚拟机,执行lua脚本,最后得到所需的html语句。对应与lp_parse_free,释放lp_load所申请的资源

webserver需要实现接口

  • sluacgi_make_env: html需要的环境变量,实现类似cgilua的servervariable接口
  • sluacgi_make_args: 生成POST信息
  • sluacgi_post_savefile: POST文件保存接口(针对post文件,为了减少内存消耗,与cgilua实现不一样)

兼容cgilua接口列表

  • print
  • put
  • servervariable
  • header
  • httpstatus
  • lp.include
  • mkurlpath
  • mkabsoluteurl
  • splitonlast
  • splitonfirst

可优化

  • 如果是用于嵌入式系统上,建议采用thttpd,因为其完全是用单线程做处理,效率和资源使用更高效
  • 如果是单线程处理,则对lp_load和lp_parse可做下优化处理,不需要频繁申请/释放内存
  • 如果不需要支持 #!/usr/bin/env cgilua.cgi ,建议将lp_load中对lp_check_exec调用去掉,更高效一些
  • 目前暂不支持sajax,如果需要可直接加入

代码

http://download.youkuaiyun.com/source/2662100

 

lp文件格式

普通

请参考附件中的例子

文件

为了兼容cgilua,故写成如下格式

<html> 
<% cgilua.lp.include ("header.lp")%>

<tr align="center" bgcolor="#CCCCCC"> 
<td width="472" height="44" colspan="2"><div align="center"> 
    <p><font color="#0" size="4" face="Geneva, Arial, Helvetica, sans-serif"><strong>demo</strong></font></p> 
  </div></td> 
</tr>

<form method="POST" enctype="multipart/form-data" action="admin_soft_update.lp"> 
<tr bgcolor="#888888"> 
    <td>file</td> 
    <td> 
    <input type="file" name="file"> 
    </td> 
</tr>

<tr bgcolor="#CCCCCC"> 
<td height="20" colspan="2" align="center"><div align="right"> 
    <input type="submit" value="put"> 
</div></td> 
</tr> 
</form> 
<% 
local fs_dir = 'www/uploads/' 
local msg = nil

local function xavante_save() 
    local f = cgilua.POST.file 
    if f and next(f) then 
        local _, name = cgilua.splitonlast(f.filename) 
        local file1 = f.file 
        os.execute('rm -rf '..fs_dir..'*') 
        os.execute('mkdir '..fs_dir) 
        local dest = io.open(fs_dir..name, "wb") 
        if dest then 
            local bytes = file1:read("*a") 
            dest:write(bytes) 
            dest:close() 
        end 
        return true, name 
    end 
    return false 
end

local function sluacgi_save() 
    local filename = cgilua.POST.filename 
    if filename then 
        local _, name = cgilua.splitonlast(filename) 
        os.execute('rm -rf '..fs_dir..'*') 
        os.execute('mkdir '..fs_dir) 
        cgilua.savefile(fs_dir..name) 
        return true, name 
    end 
    return false 
end

function save_file() 
    if cgilua.sluacgi_ver then 
        return sluacgi_save() 
    else 
        return xavante_save() 
    end 
end

    local ret, name = save_file() 
    if ret then 
            msg = 'success' 
    else 
            msg = 'failure' 
    end 
%>

    </table> 
<p>this is a demo</p> 
<% cgilua.lp.include ("buttom.lp")%>

</table> 
</form> 
</center>

<script language="javascript"> 
<% 
    if( msg ) then 
    cgilua.put("alert('"..msg.."')") 
    end 
%> 
</script> 
</body> 
</html>


工程文件说明

源码中用到了lua和tolua++的第三方库,下载地址为:

lua:  http://www.lua.org/download.html

tolua++: http://www.codenix.com/~tolua/

下载下来后解压放入sluacgi目录, 然后修改mongoose项目属性的中的addtational include Directories 中的包含路径,编译即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值