aliyun-oss-sdk 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -0
- data/Gemfile +1 -0
- data/README.md +12 -10
- data/Rakefile +10 -0
- data/aliyun-oss.gemspec +2 -2
- data/lib/aliyun/oss.rb +4 -11
- data/lib/aliyun/oss/authorization.rb +59 -27
- data/lib/aliyun/oss/client.rb +137 -62
- data/lib/aliyun/oss/client/bucket_multiparts.rb +43 -0
- data/lib/aliyun/oss/client/bucket_objects.rb +111 -0
- data/lib/aliyun/oss/client/buckets.rb +50 -0
- data/lib/aliyun/oss/client/clients.rb +54 -0
- data/lib/aliyun/oss/error.rb +43 -0
- data/lib/aliyun/oss/http.rb +65 -23
- data/lib/aliyun/oss/struct.rb +26 -0
- data/lib/aliyun/oss/struct/bucket.rb +252 -0
- data/lib/aliyun/oss/struct/cors.rb +65 -0
- data/lib/aliyun/oss/struct/lifecycle.rb +73 -0
- data/lib/aliyun/oss/struct/logging.rb +33 -0
- data/lib/aliyun/oss/struct/multipart.rb +101 -0
- data/lib/aliyun/oss/struct/object.rb +71 -0
- data/lib/aliyun/oss/struct/part.rb +48 -0
- data/lib/aliyun/oss/struct/referer.rb +21 -0
- data/lib/aliyun/oss/struct/website.rb +13 -0
- data/lib/aliyun/oss/utils.rb +41 -1
- data/lib/aliyun/oss/version.rb +1 -1
- data/lib/aliyun/oss/xml_generator.rb +174 -0
- data/todo.md +5 -0
- data/wiki/bucket.md +20 -20
- data/wiki/cors.md +59 -0
- data/wiki/error.md +42 -31
- data/wiki/get_start.md +24 -7
- data/wiki/installation.md +2 -2
- data/wiki/lifecycle.md +75 -0
- data/wiki/multipart.md +7 -5
- data/wiki/object.md +16 -12
- metadata +48 -6
- data/lib/aliyun/oss/multipart/part.rb +0 -32
- data/lib/aliyun/oss/rule/cors.rb +0 -63
- data/lib/aliyun/oss/rule/lifecycle.rb +0 -61
@@ -0,0 +1,43 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
class Client
|
4
|
+
module BucketMultiparts
|
5
|
+
# Init a Multipart Upload Event
|
6
|
+
#
|
7
|
+
# @param (see #bucket_init_multipart)
|
8
|
+
#
|
9
|
+
# @raise [RequestError]
|
10
|
+
#
|
11
|
+
# @return [Aliyun::Oss::Struct::Multipart]
|
12
|
+
#
|
13
|
+
# @see Client#bucket_init_multipart
|
14
|
+
def init(*args)
|
15
|
+
result = client.bucket_init_multipart(*args).parsed_response
|
16
|
+
|
17
|
+
multipart = Utils.dig_value(result, 'InitiateMultipartUploadResult')
|
18
|
+
Struct::Multipart.new((multipart || {}).merge(client: client))
|
19
|
+
end
|
20
|
+
|
21
|
+
# List exist Multipart Upload Events of bucket
|
22
|
+
#
|
23
|
+
# @param (see #bucket_list_multiparts)
|
24
|
+
#
|
25
|
+
# @option (see #bucket_list_multiparts)
|
26
|
+
#
|
27
|
+
# @raise [RequestError]
|
28
|
+
#
|
29
|
+
# @return [Array<Aliyun::Oss::Struct::Multipart>]
|
30
|
+
#
|
31
|
+
# @see Client#bucket_list_multiparts
|
32
|
+
def list(*args)
|
33
|
+
result = client.bucket_list_multiparts(*args).parsed_response
|
34
|
+
|
35
|
+
multipart_keys = %w(ListMultipartUploadsResult Upload)
|
36
|
+
Utils.wrap(Utils.dig_value(result, *multipart_keys)).map do |multipart|
|
37
|
+
Struct::Multipart.new(multipart.merge(client: client))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
class Client
|
4
|
+
module BucketObjects
|
5
|
+
# List objects of bucket
|
6
|
+
#
|
7
|
+
# @param (see #bucket_list_objects)
|
8
|
+
#
|
9
|
+
# @option (see #bucket_list_objects)
|
10
|
+
#
|
11
|
+
# @raise [RequestError]
|
12
|
+
#
|
13
|
+
# @return [Array<Aliyun::Oss::Struct::Object>]
|
14
|
+
#
|
15
|
+
# @see Client#bucket_list_objects
|
16
|
+
def list(*args)
|
17
|
+
result = client.bucket_list_objects(*args).parsed_response
|
18
|
+
|
19
|
+
object_keys = %w(ListBucketResult Contents)
|
20
|
+
Utils.wrap(Utils.dig_value(result, *object_keys)).map do |object|
|
21
|
+
Struct::Object.new(object.merge(client: client))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# create object of bucket
|
26
|
+
#
|
27
|
+
# @param (see #bucket_create_object)
|
28
|
+
#
|
29
|
+
# @raise [RequestError]
|
30
|
+
#
|
31
|
+
# @return [true]
|
32
|
+
#
|
33
|
+
# @see Client#bucket_create_object
|
34
|
+
def create(*args)
|
35
|
+
!!client.bucket_create_object(*args)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Delete object for bucket
|
39
|
+
#
|
40
|
+
# @param (see #bucket_delete_object)
|
41
|
+
#
|
42
|
+
# @raise [RequestError]
|
43
|
+
#
|
44
|
+
# @return [true]
|
45
|
+
#
|
46
|
+
# @see Client#bucket_delete_object
|
47
|
+
def delete(*args)
|
48
|
+
!!client.bucket_delete_object(*args)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Delete objects for bucket
|
52
|
+
#
|
53
|
+
# @param (see #bucket_delete_objects)
|
54
|
+
#
|
55
|
+
# @raise [RequestError]
|
56
|
+
#
|
57
|
+
# @return [true]
|
58
|
+
#
|
59
|
+
# @see Client#bucket_delete_objects
|
60
|
+
def delete_multiple(*args)
|
61
|
+
!!client.bucket_delete_objects(*args)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Copy from existing object
|
65
|
+
#
|
66
|
+
# @param (see #bucket_copy_object)
|
67
|
+
#
|
68
|
+
# @option (see #bucket_copy_object)
|
69
|
+
#
|
70
|
+
# @raise [RequestError]
|
71
|
+
#
|
72
|
+
# @return [true]
|
73
|
+
#
|
74
|
+
# @see Client#bucket_copy_object
|
75
|
+
def copy(*args)
|
76
|
+
!!client.bucket_copy_object(*args)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get Object
|
80
|
+
#
|
81
|
+
# @param (see #bucket_get_object)
|
82
|
+
#
|
83
|
+
# @option (see #bucket_get_object)
|
84
|
+
#
|
85
|
+
# @raise [RequestError]
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
#
|
89
|
+
# @see Client#bucekt_get_object
|
90
|
+
def get(*args)
|
91
|
+
client.bucket_get_object(*args).body
|
92
|
+
end
|
93
|
+
|
94
|
+
# Append data to a object, will create Appendable object
|
95
|
+
#
|
96
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject Append Object
|
97
|
+
#
|
98
|
+
# @param (see #bucket_append_object)
|
99
|
+
#
|
100
|
+
# @raise (see #bucket_append_object)
|
101
|
+
#
|
102
|
+
# @return [true]
|
103
|
+
#
|
104
|
+
# @see Client#bucket_append_object
|
105
|
+
def append(*args)
|
106
|
+
!!client.bucket_append_object(*args)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
class Client
|
4
|
+
module Buckets
|
5
|
+
# List buckets
|
6
|
+
#
|
7
|
+
# @param (see #list_buckets)
|
8
|
+
# @option (see #list_buckets)
|
9
|
+
#
|
10
|
+
# @return [Array<Aliyun::Oss::Struct::Bucket>]
|
11
|
+
#
|
12
|
+
# @see Client#list_buckets
|
13
|
+
def list(options = {})
|
14
|
+
result = client.list_buckets(options).parsed_response
|
15
|
+
|
16
|
+
bucket_keys = %w(ListAllMyBucketsResult Buckets Bucket)
|
17
|
+
Utils.wrap(Utils.dig_value(result, *bucket_keys)).map do |bucket_hash|
|
18
|
+
Struct::Bucket.new(bucket_hash).tap do |bucket|
|
19
|
+
dup_client = client.clone
|
20
|
+
dup_client.bucket = bucket.name
|
21
|
+
bucket.client = dup_client
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create bucket
|
27
|
+
#
|
28
|
+
# @param (see #bucket_create)
|
29
|
+
#
|
30
|
+
# @return [true]
|
31
|
+
#
|
32
|
+
# @see Client#bucket_create
|
33
|
+
def create(*args)
|
34
|
+
!!client.bucket_create(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Delete bucket
|
38
|
+
#
|
39
|
+
# @param (see #bucket_delete)
|
40
|
+
#
|
41
|
+
# @return [true]
|
42
|
+
#
|
43
|
+
# @see Client#bucket_delete
|
44
|
+
def delete(*args)
|
45
|
+
!!client.bucket_delete(*args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
#
|
4
|
+
# Here is some services used to make object based API possible, they are all contains a reference to instance of client, which used to do the real job.
|
5
|
+
#
|
6
|
+
# buckets: used to do many buckets operations eg: #list, #create, #delete
|
7
|
+
#
|
8
|
+
# client.buckets
|
9
|
+
#
|
10
|
+
# bucket_objects: used to do some operation on objects eg: #list, #create, :delete, #copy
|
11
|
+
#
|
12
|
+
# client.bucket_objects
|
13
|
+
#
|
14
|
+
# bucket_multiparts: used to do some operation for multiparts eg: #init, #list
|
15
|
+
#
|
16
|
+
# client.bucket_multiparts
|
17
|
+
#
|
18
|
+
#
|
19
|
+
class Client
|
20
|
+
def buckets
|
21
|
+
@services[:buckets] ||= Client::BucketsService.new(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def bucket_objects
|
25
|
+
@services[:bucket_objects] ||= Client::BucketObjectsService.new(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def bucket_multiparts
|
29
|
+
@services[:bucket_multiparts] ||= \
|
30
|
+
Client::BucketMultipartsService.new(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
ClientService = ::Struct.new(:client)
|
34
|
+
|
35
|
+
require 'aliyun/oss/client/buckets'
|
36
|
+
|
37
|
+
class BucketsService < ClientService
|
38
|
+
include Client::Buckets
|
39
|
+
end
|
40
|
+
|
41
|
+
require 'aliyun/oss/client/bucket_objects'
|
42
|
+
|
43
|
+
class BucketObjectsService < ClientService
|
44
|
+
include Client::BucketObjects
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'aliyun/oss/client/bucket_multiparts'
|
48
|
+
|
49
|
+
class BucketMultipartsService < ClientService
|
50
|
+
include Client::BucketMultiparts
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# [Aliyun::Oss::RequestError] when OSS give a Non 2xx response
|
6
|
+
class RequestError < Error
|
7
|
+
# Error Code defined by OSS
|
8
|
+
attr_reader :code
|
9
|
+
|
10
|
+
# Error Message defined by OSS
|
11
|
+
attr_reader :message
|
12
|
+
|
13
|
+
# It's the UUID to uniquely identifies this request;
|
14
|
+
# When you can't solve the problem, you can request help from the OSS development engineer with the RequestId.
|
15
|
+
attr_reader :request_id
|
16
|
+
|
17
|
+
# The Origin Httparty Response
|
18
|
+
attr_reader :origin_response
|
19
|
+
|
20
|
+
def initialize(response)
|
21
|
+
if (error_values = response.parsed_response['Error']).empty?
|
22
|
+
@code = response.code
|
23
|
+
@message = response.message
|
24
|
+
else
|
25
|
+
@code = error_values['Code']
|
26
|
+
@message = error_values['Message']
|
27
|
+
end
|
28
|
+
@request_id = response.headers['x-oss-request-id']
|
29
|
+
@origin_response = response
|
30
|
+
super("#{@request_id} - #{@code}: #{@message}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class MultipartPartNumberEmpty < Error; end
|
35
|
+
class MultipartUploadIdEmpty < Error; end
|
36
|
+
class MultipartSourceBucketEmptyError < Error; end
|
37
|
+
class MultipartSourceKeyEmptyError < Error; end
|
38
|
+
class MultipartPartsEmptyError < Error; end
|
39
|
+
|
40
|
+
class InvalidCorsRuleError < Error; end
|
41
|
+
class InvalidLifeCycleRuleError < Error; end
|
42
|
+
end
|
43
|
+
end
|
data/lib/aliyun/oss/http.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'aliyun/oss/error'
|
3
|
+
|
1
4
|
module Aliyun
|
2
5
|
module Oss
|
3
6
|
class Http # nodoc
|
@@ -39,25 +42,58 @@ module Aliyun
|
|
39
42
|
private
|
40
43
|
|
41
44
|
def request(verb, resource, options = {})
|
42
|
-
|
43
|
-
headers =
|
45
|
+
query = options.fetch(:query, {})
|
46
|
+
headers = options.fetch(:headers, {})
|
47
|
+
body = options.delete(:body)
|
48
|
+
|
49
|
+
append_headers!(headers, verb, body, options)
|
50
|
+
|
51
|
+
path = api_endpoint(headers['Host']) + resource
|
52
|
+
options = { headers: headers, query: query, body: body }
|
44
53
|
|
45
|
-
|
46
|
-
|
47
|
-
|
54
|
+
wrap(HTTParty.__send__(verb.downcase, path, options))
|
55
|
+
end
|
56
|
+
|
57
|
+
def wrap(response)
|
58
|
+
case response.code
|
59
|
+
when 200..299
|
60
|
+
response
|
61
|
+
else
|
62
|
+
fail RequestError, response
|
48
63
|
end
|
64
|
+
end
|
49
65
|
|
50
|
-
|
66
|
+
def append_headers!(headers, verb, body, options)
|
67
|
+
append_default_headers!(headers)
|
68
|
+
append_body_headers!(headers, body)
|
69
|
+
append_host_headers!(headers, options[:bucket], options[:location])
|
70
|
+
append_authorization_headers!(headers, verb, options)
|
71
|
+
end
|
51
72
|
|
52
|
-
|
53
|
-
|
54
|
-
|
73
|
+
def append_default_headers!(headers)
|
74
|
+
headers.merge!(default_headers)
|
75
|
+
end
|
55
76
|
|
56
|
-
|
57
|
-
|
58
|
-
.hash_slice(options.merge(headers: headers), :query, :headers, :body)
|
77
|
+
def append_body_headers!(headers, body)
|
78
|
+
return headers unless body
|
59
79
|
|
60
|
-
|
80
|
+
unless headers.key?('Content-MD5')
|
81
|
+
headers.merge!('Content-MD5' => Utils.md5_digest(body))
|
82
|
+
end
|
83
|
+
|
84
|
+
return if headers.key?('Content-Length')
|
85
|
+
headers.merge!('Content-Length' => Utils.content_size(body).to_s)
|
86
|
+
end
|
87
|
+
|
88
|
+
def append_host_headers!(headers, bucket, location)
|
89
|
+
headers.merge!('Host' => get_host(bucket, location))
|
90
|
+
end
|
91
|
+
|
92
|
+
def append_authorization_headers!(headers, verb, options)
|
93
|
+
auth_key = get_auth_key(
|
94
|
+
options.merge(verb: verb, headers: headers, date: headers['Date'])
|
95
|
+
)
|
96
|
+
headers.merge!('Authorization' => auth_key)
|
61
97
|
end
|
62
98
|
|
63
99
|
def get_auth_key(options)
|
@@ -66,28 +102,34 @@ module Aliyun
|
|
66
102
|
|
67
103
|
def default_headers
|
68
104
|
{
|
69
|
-
'User-Agent' =>
|
70
|
-
"(#{RbConfig::CONFIG['host_os']} ruby-#{RbConfig::CONFIG['ruby_version']})",
|
105
|
+
'User-Agent' => user_agent,
|
71
106
|
'Date' => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
72
107
|
}
|
73
108
|
end
|
74
109
|
|
75
|
-
def get_host(
|
76
|
-
if
|
77
|
-
"#{
|
78
|
-
elsif
|
79
|
-
"#{
|
110
|
+
def get_host(bucket, location)
|
111
|
+
if location && bucket
|
112
|
+
"#{bucket}.#{location}.aliyuncs.com"
|
113
|
+
elsif bucket
|
114
|
+
"#{bucket}.#{@host}"
|
80
115
|
else
|
81
116
|
@host
|
82
117
|
end
|
83
118
|
end
|
84
119
|
|
85
120
|
def default_content_type
|
86
|
-
{
|
121
|
+
{
|
122
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
def api_endpoint(host)
|
127
|
+
"http://#{host}"
|
87
128
|
end
|
88
129
|
|
89
|
-
def
|
90
|
-
"
|
130
|
+
def user_agent
|
131
|
+
"aliyun-oss-sdk-ruby/#{Aliyun::Oss::VERSION} " \
|
132
|
+
"(#{RbConfig::CONFIG['host_os']} ruby-#{RbConfig::CONFIG['ruby_version']})"
|
91
133
|
end
|
92
134
|
end
|
93
135
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Aliyun
|
2
|
+
module Oss
|
3
|
+
module Struct
|
4
|
+
class Base
|
5
|
+
def initialize(attributes = {})
|
6
|
+
attributes.each do |key, value|
|
7
|
+
m = "#{Utils.underscore(key)}=".to_sym
|
8
|
+
send(m, value) if self.respond_to?(m)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'aliyun/oss/struct/bucket'
|
17
|
+
require 'aliyun/oss/struct/object'
|
18
|
+
require 'aliyun/oss/struct/multipart'
|
19
|
+
|
20
|
+
require 'aliyun/oss/struct/cors'
|
21
|
+
require 'aliyun/oss/struct/lifecycle'
|
22
|
+
require 'aliyun/oss/struct/referer'
|
23
|
+
require 'aliyun/oss/struct/website'
|
24
|
+
require 'aliyun/oss/struct/logging'
|
25
|
+
|
26
|
+
require 'aliyun/oss/struct/part'
|