fix(ngx): form_upload_to_compress errors; moicen music-room nginx vars for Lua uploads
Made-with: Cursor
This commit is contained in:
+111
-28
@@ -1,49 +1,132 @@
|
|||||||
server {
|
server {
|
||||||
# https://serverfault.com/questions/798734/use-variable-for-server-name-in-nginx#
|
|
||||||
# server_name $servername;
|
|
||||||
server_name "music-room.moicen.com";
|
server_name "music-room.moicen.com";
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
client_max_body_size 20M;
|
client_max_body_size 20M;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/moicen.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/moicen.com/privkey.pem;
|
||||||
|
|
||||||
|
# 与 admin.moicen.com 保持一致:本域直接命中 /api/ngx/image/* Lua 时需 tmp、convert、又拍参数
|
||||||
|
set $tmp_file_dir "/file_upload";
|
||||||
|
set $task_server "http://127.0.0.1:8080";
|
||||||
|
set $huiwing_htyts_rust "127.0.0.1:3003";
|
||||||
|
set $huiwing_htyproc_rust "127.0.0.1:3004";
|
||||||
|
set $htyuc "http://127.0.0.1:3000";
|
||||||
set $resty_loc "/usr/local/openresty";
|
set $resty_loc "/usr/local/openresty";
|
||||||
|
set $convert "/usr/bin/convert";
|
||||||
|
set $upyun_operator "moicen";
|
||||||
|
set $upyun_password "NyJ51zRwFApY9Wo9EHJMrb8GI9YtvpVN";
|
||||||
|
set $upyun_bucket "moicen";
|
||||||
|
set $upyun_directory "music-room";
|
||||||
|
set $upyun_domain "https://upyun.moicen.com";
|
||||||
|
set $upyun_cdn "https://upyun.moicen.com/";
|
||||||
|
set $wx_domain "wx.moicen.com";
|
||||||
|
set $upt_huiwings_secret "C5E4B01EC86A4CE8A84871EA2C826DD1";
|
||||||
|
set $upt_moicen_secret "339666FBB93C46D7B00D9F6E790C6C18";
|
||||||
|
set $upt_alchemy_secret "0D32E581A445404FA4C306709724FA07";
|
||||||
|
set $upt_duration 3600;
|
||||||
|
|
||||||
# disable in local test env
|
root /usr/local/openresty/nginx/html/music-room;
|
||||||
ssl_certificate /etc/letsencrypt/live/moicen.com/fullchain.pem; # managed by Certbot
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/moicen.com/privkey.pem; # managed by Certbot
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
proxy_set_header Host "music-room.moicen.com";
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
# disable in local test env
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Host $remote_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
root $resty_loc/nginx/html/music-room;
|
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
# 公众号校验 炼金工坊
|
location = /MP_verify_Jo6pKmy43wx7S5Sh.txt {
|
||||||
location /MP_verify_Jo6pKmy43wx7S5Sh.txt {
|
default_type text/plain;
|
||||||
return 200 'Jo6pKmy43wx7S5Sh';
|
return 200 'Jo6pKmy43wx7S5Sh';
|
||||||
}
|
}
|
||||||
|
|
||||||
# 公众号校验 慧添翼音乐教室
|
location = /MP_verify_xDbyXEtPHigY8dCN.txt {
|
||||||
location /MP_verify_xDbyXEtPHigY8dCN.txt {
|
default_type text/plain;
|
||||||
return 200 'xDbyXEtPHigY8dCN';
|
return 200 'xDbyXEtPHigY8dCN';
|
||||||
}
|
}
|
||||||
|
|
||||||
# 小程序业务域名校验
|
location = /wy7of6ofMw.txt {
|
||||||
location /wy7of6ofMw.txt {
|
default_type text/plain;
|
||||||
return 200 'aa91a8d33359e82465dcc0aae9284b27';
|
return 200 'aa91a8d33359e82465dcc0aae9284b27';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /api/v1/kc/ {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header HtyHost $host;
|
||||||
|
proxy_pass http://127.0.0.1:3002/api/v1/kc/;
|
||||||
|
}
|
||||||
|
location /api/v1/clazz/ {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header HtyHost $host;
|
||||||
|
proxy_pass http://127.0.0.1:3002/api/v1/clazz/;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
location /api/v1/ws/ {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header HtyHost $host;
|
||||||
|
proxy_pass http://127.0.0.1:3001/api/v1/ws/;
|
||||||
|
}
|
||||||
|
location /api/v1/uc/ {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header HtyHost $host;
|
||||||
|
proxy_pass http://127.0.0.1:3000/api/v1/uc/;
|
||||||
|
}
|
||||||
|
location /api/v1/ts/ {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header HtyHost $host;
|
||||||
|
proxy_pass http://127.0.0.1:3003/api/v1/ts/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ngx/image/upload {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/old_upload.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/wx_upload_single {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/wx_upload_single.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/form_upload_to_combine {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/form_upload_to_combine.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/wx_upload_to_combine {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/wx_upload_to_combine.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/form_upload_to_compress {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/form_upload_to_compress.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/combine {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/combine.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/check {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/check_file.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/upload_combined {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/upload_combined_image.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/image/upyun_remove {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/upyun_remove.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/audio/upload {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/upload_audio.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/audio/convert {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/convert_audio.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/upt {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/upt.lua;
|
||||||
|
}
|
||||||
|
location /api/ngx/convert/test {
|
||||||
|
content_by_lua_file /usr/local/openresty/nginx/scripts/test.lua;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
proxy_set_header Host "music-room.moicen.com";
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Host $remote_addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name "music-room.moicen.com";
|
server_name "music-room.moicen.com";
|
||||||
location / {
|
location / {
|
||||||
return 301 https://$host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,34 @@ ngx.log(ngx.INFO, "sudoerToken ", sudoerToken)
|
|||||||
|
|
||||||
verify(httpc, authHeader, sudoerToken)
|
verify(httpc, authHeader, sudoerToken)
|
||||||
|
|
||||||
|
--- @param disposition_val string raw Content-Disposition header value
|
||||||
|
local function filename_from_disposition(disposition_val)
|
||||||
|
if not disposition_val then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local m = ngx.re.match(disposition_val, [[filename\*=UTF-8''([^;\s]+)]], "ijo")
|
||||||
|
if m and m[1] then
|
||||||
|
return ngx.unescape_uri(m[1])
|
||||||
|
end
|
||||||
|
m = ngx.re.match(disposition_val, [[filename="([^"]+)"]], "ijo")
|
||||||
|
if m and m[1] then
|
||||||
|
return m[1]
|
||||||
|
end
|
||||||
|
m = ngx.re.match(disposition_val, [[filename=([^;\s]+)]], "ijo")
|
||||||
|
if m and m[1] then
|
||||||
|
return m[1]
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function extension_from_filename(fn)
|
||||||
|
if not fn then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local em = ngx.re.match(fn, [[\.([A-Za-z0-9]+)$]], "ijo")
|
||||||
|
return em and em[1] or nil
|
||||||
|
end
|
||||||
|
|
||||||
local function read_form_file()
|
local function read_form_file()
|
||||||
local chunk_size = 4096
|
local chunk_size = 4096
|
||||||
local form, err = upload:new(chunk_size)
|
local form, err = upload:new(chunk_size)
|
||||||
@@ -24,77 +52,107 @@ local function read_form_file()
|
|||||||
ngx.log(ngx.ERR, "failed to new upload: ", err)
|
ngx.log(ngx.ERR, "failed to new upload: ", err)
|
||||||
ngx.exit(500)
|
ngx.exit(500)
|
||||||
end
|
end
|
||||||
--uuid.seed()
|
|
||||||
|
|
||||||
local file_dir = ngx.var.tmp_file_dir
|
local file_dir = ngx.var.tmp_file_dir
|
||||||
|
local convert = ngx.var.convert
|
||||||
|
|
||||||
|
if not file_dir or file_dir == "" then
|
||||||
|
ngx.status = 500
|
||||||
|
ngx.log(ngx.ERR, "tmp_file_dir is not set in nginx (set $tmp_file_dir).")
|
||||||
|
ngx.say("server misconfiguration: tmp_file_dir")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not convert or convert == "" then
|
||||||
|
ngx.status = 500
|
||||||
|
ngx.log(ngx.ERR, "ImageMagick NOT FOUND (set $convert).")
|
||||||
|
ngx.say("server misconfiguration: convert")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 确保临时目录存在(避免 worker 无权限写根路径等导致 io.open 失败)
|
||||||
|
os.execute("mkdir -p " .. file_dir)
|
||||||
|
|
||||||
local file
|
local file
|
||||||
local file_name
|
local file_name
|
||||||
local files = {}
|
local files = {}
|
||||||
local output_file = {}
|
local output_file = {}
|
||||||
|
--- 当前 multipart 部件里 Content-Disposition 里的文件名(用于扩展名回退)
|
||||||
local convert = ngx.var.convert
|
local pending_disp_filename
|
||||||
|
|
||||||
if not convert then
|
|
||||||
ngx.status = 500
|
|
||||||
ngx.log(ngx.ERR, "ImageMagick NOT FOUND.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local type, res, err = form:read()
|
local typ, res, read_err = form:read()
|
||||||
|
|
||||||
if not type then
|
if not typ then
|
||||||
ngx.say("FAILED TO READ *UPLOAD IMAGE* -> ", err)
|
ngx.status = 500
|
||||||
|
ngx.log(ngx.ERR, "FAILED TO READ upload: ", read_err)
|
||||||
|
ngx.say("FAILED TO READ *UPLOAD IMAGE* -> ", read_err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if type == "header" then
|
if typ == "header" then
|
||||||
--"Content-Disposition","form-data; name=\"files[]\"; filename=\"Song-of-joy.png\""
|
|
||||||
--"Content-Type","image\/png"
|
|
||||||
local key = res[1]
|
local key = res[1]
|
||||||
local val = res[2]
|
local val = res[2]
|
||||||
if key == "Content-Type" then
|
if key == "Content-Disposition" then
|
||||||
local ext = ngx.re.match(val, [[(\w+)\/(\w+)]], "jo")[2]
|
pending_disp_filename = filename_from_disposition(val)
|
||||||
|
elseif key == "Content-Type" then
|
||||||
|
local mt = ngx.re.match(val, [[(\w+)/([\w\-\+\.]+)]], "jo")
|
||||||
|
local ext = mt and mt[2] or nil
|
||||||
|
if ext then
|
||||||
|
ext = string.lower(ext)
|
||||||
|
if ext == "jpeg" then
|
||||||
|
ext = "jpg"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not ext and pending_disp_filename then
|
||||||
|
ext = extension_from_filename(pending_disp_filename)
|
||||||
|
if ext then
|
||||||
|
ext = string.lower(ext)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not ext then
|
||||||
|
ngx.status = 400
|
||||||
|
ngx.log(ngx.ERR, "cannot derive extension; Content-Type=", val)
|
||||||
|
ngx.say("cannot derive image file extension")
|
||||||
|
return
|
||||||
|
end
|
||||||
file_name = uuid.uuid() .. "." .. ext
|
file_name = uuid.uuid() .. "." .. ext
|
||||||
end
|
|
||||||
|
|
||||||
if file_name then
|
|
||||||
file = io.open(file_dir .. "/" .. file_name, "w+")
|
file = io.open(file_dir .. "/" .. file_name, "w+")
|
||||||
ngx.log(ngx.INFO, "FILENAME -> ", file_name)
|
ngx.log(ngx.INFO, "FILENAME -> ", file_name)
|
||||||
if not file then
|
if not file then
|
||||||
|
ngx.status = 500
|
||||||
|
ngx.log(ngx.ERR, "failed to open temp file under ", file_dir, " name=", file_name)
|
||||||
ngx.say("failed to open file ", file_name)
|
ngx.say("failed to open file ", file_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
pending_disp_filename = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif type == "body" then
|
elseif typ == "body" then
|
||||||
if file then
|
if file then
|
||||||
file:write(res)
|
file:write(res)
|
||||||
-- sha1:update(res)
|
|
||||||
end
|
end
|
||||||
elseif type == "part_end" then
|
elseif typ == "part_end" then
|
||||||
if file then
|
if file then
|
||||||
file:close()
|
file:close()
|
||||||
table.insert(files, file_name)
|
table.insert(files, file_name)
|
||||||
end
|
end
|
||||||
-- 这里要重置一下file_name,否则后面的文件保存时会导致前面已保存的文件变成空文件
|
|
||||||
-- file:flush() 和 io.flush() 都没效果
|
|
||||||
file_name = nil
|
file_name = nil
|
||||||
file = nil
|
file = nil
|
||||||
elseif type == "eof" then
|
pending_disp_filename = nil
|
||||||
-- TODO : Compress image and upload to upyun
|
elseif typ == "eof" then
|
||||||
|
local len = #files
|
||||||
local len = table.getn(files)
|
|
||||||
if len == 0 then
|
if len == 0 then
|
||||||
ngx.status = 500
|
ngx.status = 500
|
||||||
ngx.log(ngx.ERR, "No images to compress!")
|
ngx.log(ngx.ERR, "No images to compress!")
|
||||||
return ;
|
ngx.say("no image data received")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, len do
|
for i = 1, len do
|
||||||
ngx.log(ngx.INFO, 'COMPRESS FILE -> ', files[i])
|
ngx.log(ngx.INFO, 'COMPRESS FILE -> ', files[i])
|
||||||
|
|
||||||
-- Compress image
|
|
||||||
local incoming = file_dir .. "/" .. files[i]
|
local incoming = file_dir .. "/" .. files[i]
|
||||||
output_file[i] = file_dir .. "/" .. uuid.uuid() .. ".jpg"
|
output_file[i] = file_dir .. "/" .. uuid.uuid() .. ".jpg"
|
||||||
|
|
||||||
@@ -108,22 +166,17 @@ local function read_form_file()
|
|||||||
ngx.log(ngx.INFO, 'CMD RESIZE -> RESULT ', pl.dump(result))
|
ngx.log(ngx.INFO, 'CMD RESIZE -> RESULT ', pl.dump(result))
|
||||||
handle:close()
|
handle:close()
|
||||||
|
|
||||||
-- Upload compressed file to upyun
|
|
||||||
local upyun_upload = require("lib.upyun_upload")
|
local upyun_upload = require("lib.upyun_upload")
|
||||||
|
|
||||||
ngx.log(ngx.INFO, 'UPLOAD COMPRESSED IMAGE -> fullpath -> ', output_file[i])
|
ngx.log(ngx.INFO, 'UPLOAD COMPRESSED IMAGE -> fullpath -> ', output_file[i])
|
||||||
|
|
||||||
upyun_upload.upload(output_file[i], nil)
|
|
||||||
|
|
||||||
|
upyun_upload.upload(output_file[i], nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
break
|
break
|
||||||
else
|
|
||||||
-- do nothing
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
read_form_file()
|
read_form_file()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user