Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 89 additions & 23 deletions lib/ross/client.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding: utf-8
require 'rest-client'
require 'base64'

module ROSS
class Client
Expand All @@ -9,43 +10,108 @@ def initialize(options)
@bucket_name = options[:bucket_name]
@appid = options[:appid]
@appkey = options[:appkey]
@aliyun_host = "oss.aliyuncs.com"
@aliyun_host = options[:bucket_host] || "oss.aliyuncs.com"
if options[:aliyun_internal] == true
@aliyun_host = "oss-internal.aliyuncs.com"
end
end

def put(path, file, options={})
content_md5 = Digest::MD5.hexdigest(file)
content_type = options[:content_type] || "image/jpg"
def put(path, content, options={}, xoss = {})
# content_md5 = Digest::MD5.hexdigest(content)
content_type = options.has_key?(:content_type) ? options[:content_type] : "application/octet-stream"
date = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
path = "#{@bucket_name}/#{path}"
url = "http://#{@aliyun_host}/#{path}"
auth_sign = sign("PUT", path, content_md5, content_type, date)
headers = {
"Authorization" => auth_sign,
"Content-Type" => content_type,
"Content-Length" => file.length,
"Date" => date,
"Host" => @aliyun_host,
}

response = RestClient.put(url, file, headers)
"Authorization" => auth_sign("PUT", path, date, content_type, nil, xoss),
"Content-Type" => content_type,
"Date" => date,
"Host" => @aliyun_host
}
headers["Content-Length"] = content.length unless content.nil? # content can be nil
xoss.each_pair{|k,v| headers["x-oss-#{k}"] = v }
response = RestClient.put(request_url(path), content, headers)
end

def delete(path)
date = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
headers = {
"Authorization" => auth_sign("DELETE", path, date),
"Content-Type" => nil,
"Date" => date,
"Host" => @aliyun_host
}
response = RestClient.delete(request_url(path), headers)
end

def head(path)
date = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
headers = {
"Authorization" => auth_sign("HEAD", path, date),
"Content-Type" => nil,
"Date" => date,
"Host" => @aliyun_host
}
response = RestClient.head(request_url(path), headers)
end

def exists?(path)
begin
head(path)
rescue RestClient::ResourceNotFound
false
else
true
end
end

def copy(sour_path, dest_path)
put(dest_path, nil, {content_type: nil}, {'copy-source' => bucket_path(sour_path)})
end

def rename(sour_path, dest_path)
copy(sour_path, dest_path)
delete(sour_path)
end

def put_file(path, file, options = {})
put(path, File.read(file), options)
end

def get(path)
return "http://#{@bucket_name}.#{@aliyun_host}/#{path}"
def public_url(path)
"http://#{@bucket_name}.#{@aliyun_host}/#{path}"
end

alias :get :public_url

def private_url(path, expires_in = 3600)
expires_at = (8*3600 + Time.now.gmtime.to_i) + expires_in
params = {
'Expires' => expires_at,
'OSSAccessKeyId' => @appid,
'Signature' => sign('GET', path, expires_at)
}
public_url(path) + '?' + URI.encode_www_form(params)
end

private
def sign(verb, path, content_md5, content_type, date)
canonicalized_oss_headers = ''
canonicalized_resource = "/#{path}"
def sign(verb, path, date, content_type = nil, content_md5 = nil, xoss = {})
canonicalized_oss_headers = xoss.sort.map{|k,v| "x-oss-#{k}:".downcase + v + "\n"}.join
canonicalized_resource = bucket_path(path)
string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
digest = OpenSSL::Digest::Digest.new('sha1')
digest = OpenSSL::Digest.new('sha1')
h = OpenSSL::HMAC.digest(digest, @appkey, string_to_sign)
h = Base64.encode64(h)
"OSS #{@appid}:#{h}"
Base64.encode64(h).strip
end

def auth_sign(verb, path, date, content_type = nil, content_md5 = nil, xoss = {})
"OSS #{@appid}:#{sign(verb, path, date, content_type, content_md5, xoss)}"
end

def bucket_path(path)
"/#{@bucket_name}/#{path.gsub(/^\//, '')}"
end

def request_url(path)
"http://#{@aliyun_host}/#{@bucket_name}/#{URI.encode(path)}"
end
end
end
2 changes: 1 addition & 1 deletion ross.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8
Gem::Specification.new do |s|
s.name = 'ross'
s.version = '0.0.1'
s.version = '0.0.2'
s.platform = Gem::Platform::RUBY
s.summary = "ROSS is a ruby client for aliyun oss"
s.authors = ["Fizz Wu"]
Expand Down