试用 openresty/lua-resty-shell

openresty/lua-resty-shell 是当前最新rc 版本内置的shell 功能,我们可以用来执行一个脚本,以及命令
还是比较方便的。

测试集成了一个oreilly电子书下载的功能

环境准备

  • docker-compose 文件
version: "3"
services:
  nginx:
    build: ./
    ports:
    - "8888:8080"
    env_file:
    - .account.env
    volumes:
    - "./nginx_lua/:/opt/app/"
    - "./ebooks/:/opt/ebooks/"
    - "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf"
  • dockerfile
FROM openresty/openresty:1.15.8.1rc1-bionic
LABEL author="1141591465@qq.com"
WORKDIR /app
RUN apt-get install -y wget 
    && wget -O safaribooks-downloader https://github.com/rongfengliang/My-SafariBooks-Downloader/raw/master/safaribooks-downloader-linux 
    && chmod +x safaribooks-downloader
ENV PATH=$PATH:/app
  • 环境变量文件格式
    环境变量配置主要是为了方便用户账户的管理,如果在请求体没有的话,可以使用环境变量内置的
    .account.env
USERNAME=<yourid>
PASSWORD=<youpassword>
  • nginx.conf
worker_processes 1;
user root;  
events {
    worker_connections 1024;
}
env USERNAME;
env PASSWORD;
http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    lua_code_cache off;
    lua_need_request_body on;
    gzip on;
    resolver 127.0.0.11 ipv6=off;          
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    lua_package_path '/opt/app/?.lua;;';
    server {
        listen 8080;
        server_name app;
        charset utf-8;
        default_type text/html;
        location / {
           default_type text/plain;
           index index.html index.htm;
        }
        location /ebooks {
           root /opt;
           autoindex on;
           default_type application/octet-stream;
           autoindex_exact_size off;
        }
        location /download {
             content_by_lua_block {
              require("api/download")()
            }
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

    }
}

lua-resty-shell 代码部分

主要是调用oreilly 电子书下载的cli 工具(原始使用nodejs 开发,为了方便我打包为了二进制文件)
nginx_lua/api/download.lua

-- this feature use lua-resty-shell call safaribooks-downloader to do

local json = require("cjson")
local shell = require "resty.shell"
local ngx = ngx;
local function exec_shell(ebookid,storagepath,username,password)
   -- for simple use ebookid
   local filename = ebookid..".epub"
   local defaultstoragepath = (storagepath or "/app/")..filename
   -- exec shell format -b ebookid -o output directory
   -- safaribooks-downloader -b <ebookid> -u <id> -p <password> -o /Users/dalong/Desktop/testbook.epub
   return "/app/safaribooks-downloader".." -b "..ebookid.." ".." -o "..defaultstoragepath.." -u "..username.." -p "..password.." && rm -rf books"
end

local function init()
    ngx.req.read_body()
    local method_name = ngx.req.get_method()
    if method_name ~= "POST" then
       ngx.say("must with post to pass datas")
    end
    local body = ngx.req.get_body_data()
    if not body then
        if ngx.req.get_body_file() then
            return nil, "request body did not fit into client body buffer, consider raising 'client_body_buffer_size'"
        else
            return ""
        end
    end
    local downloadinfo = json.decode(body)
    if downloadinfo ~=nil then
       if downloadinfo.ebookid ==nil then
           ngx.say("please pass ebook id ")
           return nil
       end
       -- if not provide username && password use myself && set by os env
       if downloadinfo.username == nil or downloadinfo.password == nil then
           downloadinfo.username=os.getenv("USERNAME")
           downloadinfo.password=os.getenv("PASSWORD")
       end
    end
    local execommand = exec_shell(downloadinfo.ebookid,"/opt/ebooks/",downloadinfo.username,downloadinfo.password)
    -- ngx.say(execommand)
    local timeout = 300000 -- ms
    local max_size = 409600 -- byte
   -- shell 执行的核心
    local ok, stdout, stderr, reason, status =
        shell.run(execommand, nil, timeout, max_size)
    if not ok then
        return stderr
    end
    ngx.say(stdout..reason..status)
end

return init;
  • 下载效果

说明

lua-resty-shell 使用起来还是很方便的,相对以前社区的基于配置socket 服务的模型,简化了好多,对于safaribooks-downloader-linux
这个文件的生成使用的是pkg nodejs 方便的打包工具,具体的可以参考项目源码。

参考资料

https://github.com/rongfengliang/safaribooks-downloader-docker-compose
https://github.com/rongfengliang/My-SafariBooks-Downloader
https://github.com/openresty/lua-resty-shell

原文地址:https://www.cnblogs.com/rongfengliang/p/10495352.html