Lua HTTP 解析器
2017-9-12 7:25:1
收藏:0
阅读:146
评论:1
我正在尝试用 Lua 解析 HTTP POST 请求。我的实现方式可以工作,但会消耗大量的 CPU 资源。这很重要,因为它运行在嵌入式平台上。
我查看了其他的实现方式,但是它们无法适用于我,因为我的镜像硬件内存已经占满了,所以我不想使用其他的库。我自己编写了解析器,但是它使用了太多的系统资源。我的问题是如何优化这个解析器,以便减少 CPU 资源的使用。
这是一个基于 OpenWRT 的系统,所以我只有 Lua 5.1。这是核心函数,用来查找边界(在 str 变量中)。它会分块读取输入,并寻找解析器所需的边界。
另一个解决方案是使用 LUCI 库来进行重的计算,但是我不想将我的代码集成到 LUCI 中。
- 寻找模式(str),并将输入复制到输出,直到找到为止。
local function writeuntil(in_fp, str, out_fp)
local buff = ""
local ret = false
local bs = 4096 --块大小。一次性读取的数据量
local c = in_fp:read(bs)
local strStartPos = 1
while c do
local blockLen = string.len(c) --不能确保整个块都被读取了,所以获取实际块的大小
local found = string.find(c, str, 1, true) --尝试定位 str,这样我们就不必做太多的工作
if (found ~= nil) then
if found > 2 then
out_fp:write(string.sub(c, 1, found - 1))
end
ret = true
break --我们完成了
else --尝试匹配 str 直到块的结尾
local strPos = string.find(c, string.sub(str, strStartPos, strStartPos), 1, true) --尝试找到第一个字符
if strPos then --块中有起始字符
if (strPos > 1) then
out_fp:write(string.sub(c, 1, strPos - 1))
end
for i = strPos, blockLen do --迭代块
local ch = string.sub(c, i, i)
if ch == string.sub(str, strStartPos, strStartPos) then
buff = buff .. ch
if string.len(buff) == string.len(str) then
ret = true
break --我们完成了
end
strStartPos = strStartPos + 1
else --迷失方向。输出
if string.len(buff) > 0 then
out_fp:write(buff)
buff = ""
end
out_fp:write(ch)
strStartPos = 1
end
end
else
out_fp:write(c)
end
end
if ret then
break
end
c = in_fp:read(bs) --读取下一个块
end
return ret
end
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

Egor,你是对的,但我最终采用了这种方案。它现在使用的 CPU 更少。这不是完美的,因此 scp 更快(尽管它是用 C 实现的)。
--查找一个模式(str),并将输入复制到找到的位置之前的输出中。 local function writeuntil(in_fp, str, out_fp) local buff = "" local ret = false local bs = 4096 --块大小。每次读取的数据量 local c = in_fp:read(bs) local strStartPos = 1 local lastStrPos = 1 local needData = true while c do local blockLen = string.len(c) --不确定是否已经读取了整个块,因此获取实际块的大小。 local found = string.find(c, str, 1, true) --尝试定位 str,以便我们不需要很多工作。 if (found ~= nil) then if found > 1 then if #buff > 0 then out_fp:write(buff) end out_fp:write(string.sub(c, 1, found - 1)) end ret = true break --我们完成了 else --尝试匹配 str,直到块的结尾 local strPos = string.find(c, string.sub(str, strStartPos, strStartPos), lastStrPos, true) --尝试找到第一个字符 if strPos then --块中存在一个起始字符 out_fp:write(string.sub(c, lastStrPos, strPos - 1)) for i = strPos, blockLen do --迭代块 local ch = string.sub(c, i, i) if ch == string.sub(str, strStartPos, strStartPos) then buff = buff .. ch if string.len(buff) == string.len(str) then ret = true break --我们完成了 end strStartPos = strStartPos + 1 lastStrPos = i + 1 else --迷失了轨迹。输出。 if string.len(buff) > 0 then out_fp:write(buff) buff = "" end out_fp:write(ch) strStartPos = 1 if i == blockLen then needData = true else lastStrPos = i + 1 needData = false end break end end else if ret == false then if string.len(buff) > 0 then out_fp:write(buff) buff = "" end out_fp:write(string.sub(c, lastStrPos)) lastStrPos = 1 needData = true else break end end end if ret then break end if needData then c = in_fp:read(bs) --读取下一个块 lastStrPos = 1 end end return ret end