nginx下使用LUA实现边下载边发送文件内容

发布时间:2020-05-03编辑:脚本学堂
本文介绍下,在nginx服务器中,使用LUA实现边下载边发送文件内容的方法,有兴趣的朋友研究下吧。

实现:
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 函数,所以数据会堆积到内存。

有了解更多真相的朋友,欢迎分享下您的LUA使用经验。