试用 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;
- 下载效果
- 查看下载的电子书
http://localhost:8888/ebooks/
说明
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