- 发布于
使用lua上传文件到阿里云OSS
4613-–
- 作者
- 姓名
- zhli
不知道为啥阿里云OSS官网竟然没有提供lua版本的API,Google了一下只有个在nginx环境使用的库: lua-resty-http。 于是造了个轮子,供参考。
- 安装luarocks
wget https://luarocks.org/releases/luarocks-3.8.0.tar.gz
tar zxpf luarocks-3.8.0.tar.gz
cd luarocks-3.8.0
./configure --with-lua-include=/usr/local/include --lua-version=5.2
- 安装库
luarocks install luasocket
luarocks install base64
luarocks install md5
luarocks install sha1
luarocks install mimetypes
- lua脚本
upload.lua
local http = require "socket.http"
local ltn12 = require "ltn12"
local base64 = require "base64"
local md5 = require "md5"
local sha1 = require "sha1"
local mimetypes = require 'mimetypes'
local filename = arg[1]
print("begin uploading file to ali oss: " .. filename .. "\n");
local oss_config = {
accessKey = "";
secretKey = "";
bucket = "",
endpoint = ""
}
function get_file_md5(filename)
local file = io.open(filename,"rb")
if(file) then
local string = file:read("*a")
file:close()
return md5.sum(string)
end
return ''
end
function _sign(str)
local key = base64.encode(sha1.hmac_binary(oss_config.secretKey, str))
return 'OSS ' .. oss_config.accessKey .. ':' .. key
end
function _build_auth_headers(verb, content, content_type, object_name)
local bucket = oss_config.bucket
local endpoint = oss_config.endpoint
local bucket_host = bucket .. "." .. endpoint
local Date = os.date("!%a, %d %b %Y %X GMT")
local MD5 = base64.encode(get_file_md5(content))
local resource = '/' .. bucket .. '/' .. (object_name or '')
local CL = "\n"
local check_param = verb .. CL .. MD5 .. CL .. content_type .. CL .. Date .. CL .. resource
local headers = {
['Date'] = Date,
['Content-MD5'] = MD5,
['Content-Type'] = content_type,
['Authorization'] = _sign(check_param),
['Connection'] = 'keep-alive',
['Host'] = bucket_host,
['Transfer-Encoding'] = 'chunked'
}
return headers
end
function _send_http_request(url, method, headers, body)
local res_body = {}
local file = io.open(body,'rb')
if(file) then
local result, res_code = http.request{
url = url,
method = method,
headers = headers,
source = ltn12.source.file(io.open(body,'rb')),
sink = ltn12.sink.table(res_body)
}
file:close()
if res_code == 200 then
return url
end
return nil,res_body[1]
end
return nil, "file not found"
end
function put_object(content, content_type, object_name)
local headers, err = _build_auth_headers('PUT', content, content_type, object_name)
if err then return nil, err end
local url = "http://" .. headers['Host'] .. '/' .. object_name
return _send_http_request(url, "PUT", headers, content)
end
function get_file_name(file)
return file:match("^.+/(.+)$")
end
local result,err = put_object(filename, mimetypes.guess(filename) or 'application/octet-stream', "fs_records/" .. get_file_name(filename))
if(err) then
print("uploading record file failed. result: \n" .. err .. "\n")
else
print("uploading record file success. file url: " .. result .. "\n")
end
- 文件上传
lua upload.lua /var/temp.mp3