Skip to content

Instantly share code, notes, and snippets.

@vqiu
Forked from kindy/db.sql
Created June 24, 2018 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vqiu/505d8a22339b87fd7756a648258b1f63 to your computer and use it in GitHub Desktop.
Save vqiu/505d8a22339b87fd7756a648258b1f63 to your computer and use it in GitHub Desktop.
ngx_openresty file upload
" 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编码,可根据需要自己增加其它字段
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
# 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';
}
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
<!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>
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