nginx下使用LUA实现边下载边发送文件内容
时间:2014-08-14 11:38 来源:linux.it.net.cn 作者:it
实现:
Nginx配置的web服务器中,使用LUA下载文件,并发送给客户端。
需要用到curl.so动态库,例如:
复制代码代码示例:
package.path = '/usr/local/share/lua/5.1/?.lua;/usr/local/openresty/lualib/resty/?.lua;'
package.cpath = '/usr/local/lib/lua/5.1/?.so;'
require("curl")
function build_w_cb(f)
return function(s,len)
ngx.print(s)
ngx.flush(true)
--local wlen = f:write(s)
--if (wlen ~= len) then
-- return len,"writeError"
-- else
return len,nil
-- end
end
end
file = io.open("/usr/local/openresty/nginx/html/me.ts", "w")
if (file == nil) then
ngx.say ("Create File error")
return
end
ngx.header["Transfer-Encoding"] = 'chunked';
--Transfer-Encoding: chunked
--download XML File
xmlURL = "http://192.168.1.102/pxx/f1.ts"
c = curl.easy_init()
c:setopt(curl.OPT_URL, xmlURL)
c:setopt(curl.OPT_WRITEFUNCTION, build_w_cb(file))
c:setopt(curl.OPT_FOLLOWLOCATION, 1)
c:setopt(curl.OPT_USERAGENT, "ContentPreload-agent/1.0")
c:setopt(curl.OPT_COOKIEFILE, "./curlpost.cookie")
c:setopt(curl.OPT_CONNECTTIMEOUT, 5)
c:setopt(curl.OPT_TIMEOUT, 3000)
c:setopt(curl.OPT_NOSIGNAL, 1)
ret,strerr = c:perform()
file:close()
此例可以运行,不过有如下的缺点:
文件下载过程中虽然调用 ngx.print和ngx.flush,但nginx会把内容全部堆积到内存,文件完毕后才会真正发送给客户端。
原因分析:
可能是由于下载和发送为同一个线程,只有curl的 perform函数执行完毕后,才会真正发送出去,在perform函数执行的过程中,虽然调用了print函数,但是该函数只是把内容放到了内存,无法真正执行 send 函数,所以数据会堆积到内存。
(责任编辑:IT)
实现:
需要用到curl.so动态库,例如:
复制代码代码示例:
package.path = '/usr/local/share/lua/5.1/?.lua;/usr/local/openresty/lualib/resty/?.lua;'
package.cpath = '/usr/local/lib/lua/5.1/?.so;' require("curl") function build_w_cb(f) return function(s,len) ngx.print(s) ngx.flush(true) --local wlen = f:write(s) --if (wlen ~= len) then -- return len,"writeError" -- else return len,nil -- end end end file = io.open("/usr/local/openresty/nginx/html/me.ts", "w") if (file == nil) then ngx.say ("Create File error") return end ngx.header["Transfer-Encoding"] = 'chunked'; --Transfer-Encoding: chunked --download XML File xmlURL = "http://192.168.1.102/pxx/f1.ts" c = curl.easy_init() c:setopt(curl.OPT_URL, xmlURL) c:setopt(curl.OPT_WRITEFUNCTION, build_w_cb(file)) c:setopt(curl.OPT_FOLLOWLOCATION, 1) c:setopt(curl.OPT_USERAGENT, "ContentPreload-agent/1.0") c:setopt(curl.OPT_COOKIEFILE, "./curlpost.cookie") c:setopt(curl.OPT_CONNECTTIMEOUT, 5) c:setopt(curl.OPT_TIMEOUT, 3000) c:setopt(curl.OPT_NOSIGNAL, 1) ret,strerr = c:perform() file:close()
此例可以运行,不过有如下的缺点:
原因分析: |