diff --git a/dev/conf.d/music-room.conf b/dev/conf.d/music-room.conf new file mode 100644 index 0000000..442ff9b --- /dev/null +++ b/dev/conf.d/music-room.conf @@ -0,0 +1,52 @@ +server { + server_name music-room.alchemy-studio.cn; + listen 443 ssl; + + set $store_dir "/file_upload/"; # 文件存储路径 + + location / { + try_files $uri $uri/ /index.html; + proxy_set_header Host music-room.alchemy-studio.cn; + 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; + + } + + root /usr/local/openresty/nginx/html/music-room; + index index.html; + +location /test_hello_world { + #设置content type + default_type text/html ; + # HTTP Status Code 和 内容 + return 200 "hello world! "; +} + + #Upload dir + location /append_file_output { + default_type ""; + alias /file_upload; + autoidex on; + autoindex_exact_size off; + autoindex_localtime on; + } + + #Upload image file + location /upload_image { + content_by_lua_file /usr/local/openresty/resty_funcs/upload_image.lua; + } + + location /ws/ { + proxy_pass http://127.0.0.1:3001/; + proxy_set_header Host music-room.alchemy-studio.cn; + } + location /uc/ { + proxy_pass http://127.0.0.1:3000/; + proxy_set_header Host music-room.alchemy-studio.cn; + } + + ssl_certificate /etc/letsencrypt/live/music-room.alchemy-studio.cn/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/music-room.alchemy-studio.cn/privkey.pem; # managed by Certbot +} diff --git a/dev/download_image/download_image.lua b/dev/download_image/download_image.lua new file mode 100644 index 0000000..96b395b --- /dev/null +++ b/dev/download_image/download_image.lua @@ -0,0 +1,7 @@ +-- Get download image id +local download_image_id = string.match(ngx.var.request_uri, ".*/(.*)$") +ngx.log(ngx.INFO , "Download image id: " .. download_image_id) + +-- Set redirect uri +local uri = "/internal_file_upload/" .. download_image_id .. ".jpg" +return ngx.exec(uri) \ No newline at end of file diff --git a/dev/file_upload/upload_image.lua b/dev/file_upload/upload_image.lua new file mode 100644 index 0000000..cb35e6a --- /dev/null +++ b/dev/file_upload/upload_image.lua @@ -0,0 +1,223 @@ +-- Require lua modules +local upload = require "resty/upload" +local uuid = require "resty.jit-uuid" +local redis = require "resty.redis" +local cjson = require "cjson" +--------------------------------------------------------------------------------------- + +-- Functions : String split +string.split = function(s, p) + local rt= {} + string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end ) + return rt +end + +-- Functions : Get file trim +string.trim = function(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end +--------------------------------------------------------------------------------------- + +-- Init +---- Upload init +local chunk_size = 5 -- should be set to 4096 or 8192 +-- for real-world settings + +local form, error = upload:new(chunk_size) + +if not form then + ngx.log(ngx.ERR, "Fail to create new form: ", error) + ngx.exit(500) +end + +---- Automatic seeding with os.time(), LuaSocket, or ngx.time() +uuid.seed() +uuid() + +---- Redis init +------ Connect to redis +local redis_task_database = redis:new() + +redis_task_database:set_timeouts(1000, 1000, 1000) + +local ok, error = redis_task_database:connect("127.0.0.1", 6379) +if not ok then + ngx.log(ngx.ERR, "Fail to connect redis: ", error) + ngx.exit(500) +end +--------------------------------------------------------------------------------------- + +-- Save upload images +---- Upload file save path config in nginx.conf +local save_upload_file_path = ngx.var.store_dir +local file_to_save +local ret_save = false +local upload_image_filename +local save_image_filename +local upload_image_table = {} +local data_table = {} +local upload_image_index = 1 + +form:set_timeout(1000) -- 1 sec + +---- Read image file from http packet and save it +while true do + + local http_type, result, error = form:read() + + if not http_type then + ngx.log(ngx.ERR, "Failed to read form: ", error) + ngx.exit(500) + end + + if http_type == "header" then + -- Start to read http header + + local key = result[1] + local value = result[2] + + if key == "Content-Disposition" then + + -- Analyze this time upload image filename , use ; as interval + -- Like: form-data; name="testFileName"; filename="testfile.txt" + local key_value_list = string.split(value, ';') + + for _, key_value in ipairs(key_value_list) do + + local segment = string.trim(key_value) + + if segment:find("filename") then + + local key_value_file = string.split(segment, "=") + upload_image_filename = string.sub(key_value_file[2], 2, -2) + + ngx.log(ngx.INFO, "Upload origin filename: ", upload_image_filename) + + -- Save upload file + if upload_image_filename then + -- Save file name with generate uuid + save_image_filename = uuid:generate_v4() -- Generate save filename uuid + save_image_filename = save_image_filename .. '.' .. upload_image_filename:match(".+%.(%w+)$") + file_to_save = io.open(save_upload_file_path .. save_image_filename, "w+") + + if not file_to_save then + ngx.log(ngx.ERR , "Fail open file: ", save_image_filename) + ngx.exit(500) + else + ngx.log(ngx.INFO, "Success open file: ", save_image_filename) + + -- Save all upload files as a table + data_table[upload_image_index] = save_image_filename + upload_image_table[upload_image_index] = save_upload_file_path .. save_image_filename .. " " + ngx.log(ngx.INFO, "Insert upload image table "..upload_image_index.." with "..upload_image_table[upload_image_index]) + + upload_image_index = upload_image_index + 1 + end + break + end + end + end + end + + elseif http_type == "body" then + + -- Start to read http body + if file_to_save then + file_to_save:write(result) + end + + elseif http_type == "part_end" then + + -- Write to save file finish + if file_to_save then + file_to_save:close() + file_to_save = nil + end + + ret_save = true + + elseif http_type == "eof" then + -- Read file end + break + else + ngx.log(ngx.INFO, "Maybe do other things") + end +end +--------------------------------------------------------------------------------------- + +-- Show all input and may output files +if ret_save then + ngx.log(ngx.INFO, "Show all upload save files\n") + + ---- Show all upload save files + upload_image_index = upload_image_index -1 + for i = 1, upload_image_index do + ngx.log(ngx.INFO, "Save upload file is : " .. upload_image_table[i]) + end + --------------------------------------------------------------------------------------- + + -- Communicate with front end + ---- Generate task uuid + local task_uuid = uuid.generate_v4(); + --------------------------------------------------------------------------------------- + + -- Construct {key: task_id | value: [images] } in json + -- Example: + -- {"task_id":"488a8e6c556a-4271-adec--071e843c9856","data:"[\"2109aac0-556a-4271-adec-9eac494f622f.jpg\",\"488a8e6c-01e6-4cb3-af88-a1d90e04e6b8.jpg\",\"c3f76317-592f-4117-ab0d-071e843c9856.jpg\"]"} + local task_table = {} + task_table["task_id"] = task_uuid + task_table["data"] = data_table + + local task_jason = cjson.encode(task_table) + ngx.log(ngx.INFO , task_jason) -- Response to front end + --------------------------------------------------------------------------------------- + + -- Redis control + ---- Set json to redis + ok, error = redis_task_database:set(task_uuid, task_jason) + if not ok then + ngx.log(ngx.ERR , "Failed to set task json: ", error) + ngx.exit(500) + end + ngx.log(ngx.INFO , "Set redis task json result: ", ok) + + ---- Get data from redis + local result, error = redis_task_database:get(task_uuid) + if not result then + ngx.log(ngx.ERR , "Failed to get task json: ", error) + ngx.exit(500) + end + + if result == ngx.null then + ngx.log(ngx.ERR , "Not found task id") + ngx.exit(500) + end + + ngx.log(ngx.INFO, "Get redis task id: " .. task_uuid .. " | value :" .. result) + --------------------------------------------------------------------------------------- + + -- Create task + local result = ngx.location.capture( + '/mock_task_server', + { + method = ngx.HTTP_POST, + body = ngx.encode_args({task = task_jason}) + } + ) + ngx.say(result.body) + + -- Response task ID to front end + ngx.say(task_uuid) + + -- Mock a image append request from task from task server + local result = ngx.location.capture( + '/image_append', + { + method = ngx.HTTP_POST, + body = ngx.encode_args({task = task_jason}) + } + ) + ngx.say(result.body) + + +end \ No newline at end of file diff --git a/dev/image_append/image_append.lua b/dev/image_append/image_append.lua new file mode 100644 index 0000000..a2b0048 --- /dev/null +++ b/dev/image_append/image_append.lua @@ -0,0 +1,58 @@ +local uuid = require "resty.jit-uuid" +local cjson = require "cjson" + +local json_string = nil + +---- Automatic seeding with os.time(), LuaSocket, or ngx.time() +uuid.seed() +uuid() + +-- Get post json argv +local arg = ngx.req.get_post_args() +for k,v in pairs(arg) do + ngx.log(ngx.INFO , "Image append [POST] key:", k .." | ".." v:", v) + json_string = v +end + +-- Decode json string +local json = cjson.decode(json_string) +ngx.say("Image append input filename number is :" , table.getn(json.data)) +local image_append_input_files_number = table.getn(json.data) +for i = 1, image_append_input_files_number do + ngx.log(ngx.INFO , "Image append input filename is :" , json.data[i]) +end + +-- Image append +---- Upload file save path config in nginx.conf +local save_upload_file_path = ngx.var.store_dir +local append_image_table = {} +local output_image_uuid = uuid.generate_v4(); + +-- Add path to input image filename +for i = 1, image_append_input_files_number do + append_image_table[i] = save_upload_file_path .. json.data[i] .. " " + ngx.log(ngx.INFO, "Insert append image table "..i.." with "..append_image_table[i]) +end + +-- Concat input image to a command string +local append_input_images = table.concat(append_image_table) +ngx.log(ngx.INFO , "Input images list : " , append_input_images) + +-- Add path to output image filename +local append_output_image = save_upload_file_path .. output_image_uuid..".jpg "; +ngx.log(ngx.INFO , "Output image is : "..append_output_image) + +-- Debug +ngx.log(ngx.INFO , '/usr/local/ImageMagick/bin/magick convert -append '..append_input_images..' '..append_output_image) + +local call_imagemagick_cmd = io.popen('/usr/local/ImageMagick/bin/magick convert -append '..append_input_images..' '..append_output_image) +local imagemagick_cmd_replay = call_imagemagick_cmd:read("*all") +ngx.log(ngx.INFO , imagemagick_cmd_replay) + + + + + + + + diff --git a/dev/nginx.conf b/dev/nginx.conf new file mode 100644 index 0000000..6992f69 --- /dev/null +++ b/dev/nginx.conf @@ -0,0 +1,74 @@ + +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +error_log logs/error.log info; + +#pid logs/nginx.pid; + + + +events { + worker_connections 1024; +} + + +http { + lua_package_path "/usr/local/openresty/resty_funcs/?.lua;;"; + include mime.types; + default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + + #gzip on; + + + server { + serer_name alchemy-studio.cn; # managed by Certbot + root /home/nginx/website; + index index.html; + + location /wy7of6ofMw.txt { + alias /home/nginx/website/wx_verify/wy7of6ofMw.txt; + } + + location / { + try_files $uri $uri/ /index.html =404; + } + + listen [::]:443 ssl ipv6only=on; # managed by Certbot + listen 443 ssl; # managed by Certbot + ssl_certificate /etc/letsencrypt/live/alchemy-studio.cn/fullchain.pem; # managed by Certbot + ssl_certificate_key /etc/letsencrypt/live/alchemy-studio.cn/privkey.pem; # managed by Certbot + include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot + + } + + server { + + listen 80 ; + listen [::]:80 ; + server_name alchemy-studio.cn; + + location / { + return 301 https://$host$request_uri; + } + } + + include /usr/local/openresty/nginx/conf.d/music-room.conf; + #include /usr/local/openresty/nginx/conf.d/resty_funcs.conf; +} + diff --git a/prod/upload.lua b/prod/upload.lua new file mode 100644 index 0000000..e69de29