Created
December 6, 2012 05:50
-
-
Save kindy/4222068 to your computer and use it in GitHub Desktop.
ngx_openresty file upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" mysql中增加一数据库,名为nginx,编码为utf8 | |
" 增加一表,名为 uploadfile 结构为 | |
CREATE TABLE `uploadfile` ( | |
`id` int(20) NOT NULL AUTO_INCREMENT, | |
`filehash` varchar(50) DEFAULT NULL, | |
`filename` varchar(100) DEFAULT NULL, | |
`filelen` varchar(50) DEFAULT NULL, | |
`contenthash` varchar(80) DEFAULT NULL, | |
PRIMARY KEY (`id`) | |
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8; | |
" filehash为文件名的sha1编码,filename为文件名,filelen为文件大小,contenthash为文件内容的sha1编码,可根据需要自己增加其它字段 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local mylib = require "resty.mylib" | |
local args = ngx.req.get_uri_args() | |
local id = args.id | |
local filehash =args.filehash | |
if id == "" then | |
ngx.say("ID required") | |
return | |
end | |
if filehash == "" then | |
ngx.say("filehash required") | |
return | |
end | |
local filehashquote = ndk.set_var.set_quote_sql_str(filehash) | |
local filepath = "/usr/local/openresty/nginx/html/uploadfile/" | |
local mysql = require "resty.mysql" | |
local db = mysql:new() | |
db:set_timeout(30000) -- 1 sec | |
local ok, err, errno, sqlstate = db:connect({ | |
host = "127.0.0.1", | |
port = "3306", | |
database = "nginx", | |
user = "root", | |
password = "passwd", | |
max_packet_size=10485760}) | |
if not ok then | |
ngx.say("failed to connect:", err, ": ", errno ,", ", sqlstate) | |
return | |
end | |
local query = "delete from uploadfile where id =" .. tonumber(id) .. " and contenthash=" .. filehashquote | |
local res, err, errno, sqlstate = db:query(query) | |
if not res then | |
ngx.say("failed to connect: " , err , ": " , errno, " " , sqlstate) | |
return | |
end | |
if res.affected_rows == 0 then | |
ngx.say("can't find recodes in db") | |
return | |
end | |
query = "select count(*) as count from uploadfile where contenthash="..filehashquote | |
local res, err, errno, sqlstate = db:query(query) | |
if not res then | |
ngx.say("failed to connect: " , err , ": " , errno, " " , sqlstate) | |
return | |
end | |
if res[1].count == '0' then | |
local deleted = mylib.my_remove_file(filepath .. filehash) | |
if not deleted then | |
ngx.say("unable deleted the file ",filehash) | |
return | |
end | |
ngx.say(filehash, " has been deleted successful") | |
else | |
ngx.say(filehash, " has been deleted successful") | |
end | |
local ok, err = db:set_keepalive() | |
if not ok then | |
ngx.say("failed to set keepalive: ",err) | |
return | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# archive of http://blog.163.com/lhmwzy@126/blog/static/64215736201210209285365/ | |
location /file/delete { | |
content_by_lua_file 'conf/lua/delete_file.lua'; | |
} | |
location /file/upload { | |
content_by_lua_file 'conf/lua/upload_file.lua'; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module("resty.mylib", package.seeall) | |
function my_get_filename(res) | |
local filename = ngx.re.match(res,'(.+)filename="(.+)"(.*)') | |
if filename then | |
return filename[2] | |
end | |
end | |
function my_remove_file(filename) | |
return os.remove(filename) | |
end | |
function table_merge(table1, table2) | |
for i,v in ipairs(table2) do | |
table.insert(table1, v) | |
end | |
return table1 | |
end | |
function my_save_uploadfile_todb(filename,filehash,filelen,contenthash,osfilepath) | |
local mysql = require "resty.mysql" | |
local db = mysql:new() | |
db:set_timeout(30000) -- 1 sec | |
local result | |
local ok, err, errno, sqlstate = db:connect({ | |
host = "127.0.0.1", | |
port = "3306", | |
database = "nginx", | |
user = "root", | |
password = "passwd", | |
max_packet_size=10485760}) | |
if not ok then | |
ngx.say("failed to connect: " , err , ": " , errno, " " , sqlstate) | |
return | |
end | |
filename = ndk.set_var.set_quote_sql_str(filename) | |
local filehashquote = ndk.set_var.set_quote_sql_str(filehash) | |
local contenthashquote = ndk.set_var.set_quote_sql_str(contenthash) | |
local query = "insert into uploadfile (filehash,filename,filelen,contenthash) values (" .. filehashquote .. "," .. filename .. "," .. filelen .. "," .. contenthashquote .. ")" | |
local res, err, errno, sqlstate = db:query(query) | |
if not res then | |
ngx.say("failed to connect: " , err , ": " , errno, " " , sqlstate) | |
local filepath = "/usr/local/openresty/nginx/html/uploadfile/" | |
my_remove_file(osfilepath .. filehash) | |
return | |
end | |
os.rename(osfilepath..filehash,osfilepath..contenthash) | |
query = "SELECT LAST_INSERT_ID() as lastid" | |
local res1, err, errno, sqlstate = db:query(query) | |
if not res1 then | |
ngx.say("failed to connect: " , err , ": " , errno, " " , sqlstate) | |
return | |
end | |
ngx.say("db save done!", " <a href='/deleteuploadfile?id=" , res1[1].lastid , "&filehash=" , contenthash , "'>delete</a><br>") | |
ngx.say(filename," uploaded done!<br>") | |
local ok, err = db:set_keepalive() | |
if not ok then | |
ngx.say("failed to set keepalive: " ,err) | |
return | |
end | |
end | |
-- to prevent use of casual module global variables | |
getmetatable(resty.mylib).__newindex = function (table, key, val) | |
error('attempt to write to undeclared variable "' .. key .. '": ' | |
.. debug.traceback()) | |
end | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
</head> | |
<body> | |
<form action="/file/upload" method="POST" enctype="multipart/form-data"> | |
<input type="file" name="upload1" /><br /> | |
<input type="file" name="upload2" /><br /> | |
<input type="submit" value="Upload Files" /> | |
</form> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local upload = require "resty.upload" | |
local cjson = require "cjson" | |
local mylib = require "resty.mylib" | |
local resty_sha1 = require "resty.sha1" | |
local sha1 = resty_sha1:new() | |
local str = require "resty.string" | |
local chunk_size = 4096 -- should be set to 4096 or 8192 | |
-- for real-world settings | |
local form = upload:new(chunk_size) | |
local file | |
local filelen=0 | |
--local my_get_filename,my_save_uploadfile_todb | |
form:set_timeout(0) -- 1 sec | |
local filename,filenamesha1,contentsha1 | |
local osfilepath = "/usr/local/openresty/nginx/html/uploadfile/" | |
local i=0 | |
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] ~= "Content-Type" then | |
filename = mylib.my_get_filename(res[2]) | |
if filename then | |
i=i+1 | |
filenamesha1=sha1:update(filename) | |
filenamesha1 = str.to_hex(sha1:final()) | |
sha1:reset() | |
filepath = osfilepath .. filenamesha1 | |
file = io.open(filepath,"w+") | |
if not file then | |
ngx.say("failed to open file ") | |
return | |
end | |
else | |
end | |
end | |
elseif typ == "body" then | |
if file then | |
filelen= filelen + tonumber(string.len(res)) | |
file:write(res) | |
contentsha1 = sha1:update(res) | |
else | |
end | |
elseif typ == "part_end" then | |
if file then | |
file:close() | |
file = nil | |
contentsha1 = str.to_hex(sha1:final()) | |
sha1:reset() | |
ngx.say("file content sha1hash is "..contentsha1) | |
ngx.say(mylib.my_save_uploadfile_todb(filename,filenamesha1,filelen,contentsha1,osfilepath)) | |
end | |
elseif typ == "eof" then | |
break | |
else | |
end | |
end | |
if i==0 then | |
ngx.say("please upload at least one file!") | |
return | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment