diff --git a/conf/moicen/music-room.conf b/conf/moicen/music-room.conf index 7925e45..2512b0b 100644 --- a/conf/moicen/music-room.conf +++ b/conf/moicen/music-room.conf @@ -1,49 +1,132 @@ server { -# https://serverfault.com/questions/798734/use-variable-for-server-name-in-nginx# -# server_name $servername; server_name "music-room.moicen.com"; listen 443 ssl; 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 $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 - 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; + root /usr/local/openresty/nginx/html/music-room; index index.html; - # 公众号校验 炼金工坊 - location /MP_verify_Jo6pKmy43wx7S5Sh.txt { + location = /MP_verify_Jo6pKmy43wx7S5Sh.txt { + default_type text/plain; return 200 'Jo6pKmy43wx7S5Sh'; } - # 公众号校验 慧添翼音乐教室 - location /MP_verify_xDbyXEtPHigY8dCN.txt { + location = /MP_verify_xDbyXEtPHigY8dCN.txt { + default_type text/plain; return 200 'xDbyXEtPHigY8dCN'; } - # 小程序业务域名校验 - location /wy7of6ofMw.txt { + location = /wy7of6ofMw.txt { + default_type text/plain; 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 { - listen 80; - server_name "music-room.moicen.com"; - location / { - return 301 https://$host$request_uri; - } + listen 80; + server_name "music-room.moicen.com"; + location / { + return 301 https://$host$request_uri; + } } \ No newline at end of file diff --git a/scripts/form_upload_to_compress.lua b/scripts/form_upload_to_compress.lua index ac63fb9..1f458ed 100644 --- a/scripts/form_upload_to_compress.lua +++ b/scripts/form_upload_to_compress.lua @@ -17,6 +17,34 @@ ngx.log(ngx.INFO, "sudoerToken ", 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 chunk_size = 4096 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.exit(500) end - --uuid.seed() 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_name local files = {} local output_file = {} - - local convert = ngx.var.convert - - if not convert then - ngx.status = 500 - ngx.log(ngx.ERR, "ImageMagick NOT FOUND.") - return - end + --- 当前 multipart 部件里 Content-Disposition 里的文件名(用于扩展名回退) + local pending_disp_filename while true do - local type, res, err = form:read() + local typ, res, read_err = form:read() - if not type then - ngx.say("FAILED TO READ *UPLOAD IMAGE* -> ", err) + if not typ then + ngx.status = 500 + ngx.log(ngx.ERR, "FAILED TO READ upload: ", read_err) + ngx.say("FAILED TO READ *UPLOAD IMAGE* -> ", read_err) return end - if type == "header" then - --"Content-Disposition","form-data; name=\"files[]\"; filename=\"Song-of-joy.png\"" - --"Content-Type","image\/png" + if typ == "header" then local key = res[1] local val = res[2] - if key == "Content-Type" then - local ext = ngx.re.match(val, [[(\w+)\/(\w+)]], "jo")[2] + if key == "Content-Disposition" then + 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 - end - if file_name then file = io.open(file_dir .. "/" .. file_name, "w+") ngx.log(ngx.INFO, "FILENAME -> ", file_name) 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) return end + pending_disp_filename = nil end - elseif type == "body" then + elseif typ == "body" then if file then file:write(res) - -- sha1:update(res) end - elseif type == "part_end" then + elseif typ == "part_end" then if file then file:close() table.insert(files, file_name) end - -- 这里要重置一下file_name,否则后面的文件保存时会导致前面已保存的文件变成空文件 - -- file:flush() 和 io.flush() 都没效果 file_name = nil file = nil - elseif type == "eof" then - -- TODO : Compress image and upload to upyun - - local len = table.getn(files) + pending_disp_filename = nil + elseif typ == "eof" then + local len = #files if len == 0 then ngx.status = 500 ngx.log(ngx.ERR, "No images to compress!") - return ; + ngx.say("no image data received") + return end for i = 1, len do ngx.log(ngx.INFO, 'COMPRESS FILE -> ', files[i]) - -- Compress image local incoming = file_dir .. "/" .. files[i] 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)) handle:close() - -- Upload compressed file to upyun local upyun_upload = require("lib.upyun_upload") 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 break - else - -- do nothing end end end read_form_file() -