问题: 上传大文件失败或超时
解决方案:
# nginx.conf 配置
http {
client_max_body_size 100M; # 设置最大上传文件大小
client_body_temp_path /tmp/nginx_upload; # 设置临时文件目录
client_body_buffer_size 128k;
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
lua_package_path "/path/to/lua/scripts/?.lua;;";
server {
listen 80;
location /upload {
content_by_lua_file /path/to/upload.lua;
}
}
}
-- upload.lua 示例
local upload = require "resty.upload"
local cjson = require "cjson"
local chunk_size = 4096
local form = upload:new(chunk_size)
form:set_timeout(1000) -- 1秒超时
local file
local file_path
local file_name
while true do
local typ, res, err = form:read()
if not typ then
ngx.say("failed to read: ", err)
return
end
if typ == "header" then
if res[1]:lower() == "content-disposition" then
file_name = res[2]:match('filename="(.*)"')
if file_name then
file_path = "/path/to/uploads/" .. file_name
file = io.open(file_path, "w+")
if not file then
ngx.say("failed to open file: ", file_path)
return
end
end
end
elseif typ == "body" then
if file then
file:write(res)
end
elseif typ == "part_end" then
if file then
file:close()
file = nil
end
elseif typ == "eof" then
break
end
end
ngx.say(cjson.encode({
status = "success",
file_name = file_name,
file_path = file_path
}))
问题: 下载速度慢或大文件下载失败
解决方案:
location /download {
# 使用X-Accel-Redirect实现高效文件下载
internal;
alias /path/to/files;
# 开启断点续传
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_force_ranges on;
# 优化下载性能
aio on;
directio 512;
output_buffers 1 128k;
}
-- download.lua 示例
local file_path = "/path/to/files/" .. ngx.var.arg_file
local file = io.open(file_path, "rb")
if not file then
ngx.status = ngx.HTTP_NOT_FOUND
ngx.say("File not found")
return
end
local file_size = file:seek("end")
file:close()
ngx.header["Content-Type"] = "application/octet-stream"
ngx.header["Content-Disposition"] = "attachment; filename=" .. ngx.var.arg_file
ngx.header["Content-Length"] = file_size
ngx.header["Accept-Ranges"] = "bytes"
-- 使用X-Accel-Redirect提高性能
ngx.header["X-Accel-Redirect"] = "/download/" .. ngx.var.arg_file
问题: 防止恶意文件上传和非法下载
解决方案:
-- 上传安全验证
local function is_safe_filename(name)
-- 检查文件扩展名
local allowed_ext = {jpg=true, png=true, pdf=true, txt=true}
local ext = name:match("^.+(%..+)$")
if ext then
ext = ext:sub(2):lower()
if not allowed_ext[ext] then
return false
end
end
-- 防止路径遍历
if name:find("..") or name:find("/") or name:find("\\") then
return false
end
return true
end
-- 下载权限验证
local function check_download_permission(file_name)
-- 实现你的权限验证逻辑
-- 例如检查session、token等
return true
end
配置建议:
# 开启lua代码缓存
lua_code_cache on;
# 使用共享内存存储上传状态
lua_shared_dict upload_status 10m;
# 优化lua执行
lua_socket_log_errors off;
lua_check_client_abort on;
目录结构
/nginx/
├── conf/nginx.conf
├── lua/
│ ├── upload.lua
│ ├── download.lua
│ └── utils.lua
├── uploads/
└── logs/
依赖安装
luarocks install lua-resty-upload
监控与日志
分片上传
文件秒传
下载限速
limit_rate
指令CDN集成
病毒扫描
希望这个解决方案能帮助你搭建稳定高效的文件上传下载服务。根据你的具体需求,可以进一步调整和扩展这些配置。