qiniu 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +14 -0
- data/CHANGELOG.md +83 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +37 -0
- data/LICENSE +22 -0
- data/README.md +45 -0
- data/Rakefile +21 -0
- data/docs/README.md +790 -0
- data/lib/qiniu-rs.rb +2 -0
- data/lib/qiniu.rb +229 -0
- data/lib/qiniu/abstract.rb +22 -0
- data/lib/qiniu/auth.rb +25 -0
- data/lib/qiniu/config.rb +61 -0
- data/lib/qiniu/exceptions.rb +120 -0
- data/lib/qiniu/fop.rb +3 -0
- data/lib/qiniu/image.rb +38 -0
- data/lib/qiniu/log.rb +15 -0
- data/lib/qiniu/management.rb +114 -0
- data/lib/qiniu/misc.rb +35 -0
- data/lib/qiniu/resumable_upload.rb +306 -0
- data/lib/qiniu/storage.rb +5 -0
- data/lib/qiniu/tokens/access_token.rb +21 -0
- data/lib/qiniu/tokens/download_token.rb +31 -0
- data/lib/qiniu/tokens/qbox_token.rb +38 -0
- data/lib/qiniu/tokens/upload_token.rb +47 -0
- data/lib/qiniu/upload.rb +114 -0
- data/lib/qiniu/utils.rb +151 -0
- data/lib/qiniu/version.rb +17 -0
- data/qiniu.gemspec +28 -0
- data/spec/qiniu/abstract_spec.rb +30 -0
- data/spec/qiniu/image_logo_for_test.png +0 -0
- data/spec/qiniu/image_spec.rb +87 -0
- data/spec/qiniu/management_spec.rb +181 -0
- data/spec/qiniu/misc_spec.rb +59 -0
- data/spec/qiniu/qiniu_spec.rb +385 -0
- data/spec/qiniu/tokens/qbox_token_spec.rb +29 -0
- data/spec/qiniu/upload_spec.rb +184 -0
- data/spec/qiniu/utils_spec.rb +49 -0
- data/spec/qiniu/version_spec.rb +10 -0
- data/spec/spec_helper.rb +11 -0
- metadata +194 -0
data/lib/qiniu/fop.rb
ADDED
data/lib/qiniu/image.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Qiniu
|
4
|
+
module Fop
|
5
|
+
module Image
|
6
|
+
class << self
|
7
|
+
include Utils
|
8
|
+
|
9
|
+
def info(url)
|
10
|
+
Utils.http_request url + '?imageInfo', nil, {:method => :get}
|
11
|
+
end # info
|
12
|
+
|
13
|
+
def exif(url)
|
14
|
+
Utils.http_request url + '?exif', nil, {:method => :get}
|
15
|
+
end # exif
|
16
|
+
|
17
|
+
def mogrify_preview_url(source_image_url, options)
|
18
|
+
source_image_url + '?' + generate_mogrify_params_string(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_mogrify_params_string(options = {})
|
22
|
+
opts = {}
|
23
|
+
options.each do |k, v|
|
24
|
+
opts[k.to_s] = v
|
25
|
+
end
|
26
|
+
params_string = ""
|
27
|
+
keys = ["thumbnail", "gravity", "crop", "quality", "rotate", "format"]
|
28
|
+
keys.each do |key|
|
29
|
+
params_string += %Q(/#{key}/#{opts[key]}) unless opts[key].nil?
|
30
|
+
end
|
31
|
+
params_string += '/auto-orient' unless opts["auto_orient"].nil?
|
32
|
+
'imageMogr' + URI.escape(params_string)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end # module Image
|
37
|
+
end # module Fop
|
38
|
+
end # module Qiniu
|
data/lib/qiniu/log.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Qiniu
|
4
|
+
module Storage
|
5
|
+
class << self
|
6
|
+
include Utils
|
7
|
+
|
8
|
+
def buckets
|
9
|
+
Auth.request Config.settings[:rs_host] + '/buckets'
|
10
|
+
end # buckets
|
11
|
+
|
12
|
+
def mkbucket(bucket_name)
|
13
|
+
Auth.request Config.settings[:rs_host] + '/mkbucket/' + bucket_name
|
14
|
+
end # mkbucket
|
15
|
+
|
16
|
+
def stat(bucket, key)
|
17
|
+
Auth.request Config.settings[:rs_host] + '/stat/' + encode_entry_uri(bucket, key)
|
18
|
+
end # stat
|
19
|
+
|
20
|
+
def get(bucket, key, save_as = nil, expires_in = nil, version = nil)
|
21
|
+
url = Config.settings[:rs_host] + '/get/' + encode_entry_uri(bucket, key)
|
22
|
+
url += '/base/' + version unless version.nil?
|
23
|
+
url += '/attName/' + Utils.urlsafe_base64_encode(save_as) unless save_as.nil?
|
24
|
+
url += '/expires/' + expires_in.to_s if !expires_in.nil? && expires_in > 0
|
25
|
+
Auth.request url
|
26
|
+
end # get
|
27
|
+
|
28
|
+
def copy(source_bucket, source_key, target_bucket, target_key)
|
29
|
+
uri = _generate_cp_or_mv_opstr('copy', source_bucket, source_key, target_bucket, target_key)
|
30
|
+
Auth.request Config.settings[:rs_host] + uri
|
31
|
+
end # copy
|
32
|
+
|
33
|
+
def move(source_bucket, source_key, target_bucket, target_key)
|
34
|
+
uri = _generate_cp_or_mv_opstr('move', source_bucket, source_key, target_bucket, target_key)
|
35
|
+
Auth.request Config.settings[:rs_host] + uri
|
36
|
+
end # move
|
37
|
+
|
38
|
+
def delete(bucket, key)
|
39
|
+
Auth.request Config.settings[:rs_host] + '/delete/' + encode_entry_uri(bucket, key)
|
40
|
+
end # delete
|
41
|
+
|
42
|
+
def publish(domain, bucket)
|
43
|
+
encoded_domain = Utils.urlsafe_base64_encode(domain)
|
44
|
+
Auth.request Config.settings[:rs_host] + "/publish/#{encoded_domain}/from/#{bucket}"
|
45
|
+
end # publish
|
46
|
+
|
47
|
+
def unpublish(domain)
|
48
|
+
encoded_domain = Utils.urlsafe_base64_encode(domain)
|
49
|
+
Auth.request Config.settings[:rs_host] + "/unpublish/#{encoded_domain}"
|
50
|
+
end # unpublish
|
51
|
+
|
52
|
+
def drop(bucket)
|
53
|
+
Auth.request Config.settings[:rs_host] + "/drop/#{bucket}"
|
54
|
+
end # drop
|
55
|
+
|
56
|
+
def batch(command, bucket, keys)
|
57
|
+
execs = []
|
58
|
+
keys.each do |key|
|
59
|
+
encoded_uri = encode_entry_uri(bucket, key)
|
60
|
+
execs << "op=/#{command}/#{encoded_uri}"
|
61
|
+
end
|
62
|
+
Auth.request Config.settings[:rs_host] + "/batch", execs.join("&"), {:mime => "application/x-www-form-urlencoded" }
|
63
|
+
end # batch
|
64
|
+
|
65
|
+
def batch_get(bucket, keys)
|
66
|
+
batch("get", bucket, keys)
|
67
|
+
end # batch_get
|
68
|
+
|
69
|
+
def batch_stat(bucket, keys)
|
70
|
+
batch("stat", bucket, keys)
|
71
|
+
end # batch_stat
|
72
|
+
|
73
|
+
def batch_copy(*args)
|
74
|
+
_batch_cp_or_mv('copy', args)
|
75
|
+
end # batch_copy
|
76
|
+
|
77
|
+
def batch_move(*args)
|
78
|
+
_batch_cp_or_mv('move', args)
|
79
|
+
end # batch_move
|
80
|
+
|
81
|
+
def batch_delete(bucket, keys)
|
82
|
+
batch("delete", bucket, keys)
|
83
|
+
end # batch_delete
|
84
|
+
|
85
|
+
def save_as(bucket, key, source_url, op_params_string)
|
86
|
+
encoded_uri = encode_entry_uri(bucket, key)
|
87
|
+
save_as_string = '/save-as/' + encoded_uri
|
88
|
+
new_url = source_url + '?' + op_params_string + save_as_string
|
89
|
+
Auth.request new_url
|
90
|
+
end # save_as
|
91
|
+
|
92
|
+
def image_mogrify_save_as(bucket, key, source_image_url, options)
|
93
|
+
mogrify_params_string = Fop::Image.generate_mogrify_params_string(options)
|
94
|
+
save_as(bucket, key, source_image_url, mogrify_params_string)
|
95
|
+
end # image_mogrify_save_as
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def _generate_cp_or_mv_opstr(command, source_bucket, source_key, target_bucket, target_key)
|
100
|
+
source_encoded_entry_uri = encode_entry_uri(source_bucket, source_key)
|
101
|
+
target_encoded_entry_uri = encode_entry_uri(target_bucket, target_key)
|
102
|
+
%Q(/#{command}/#{source_encoded_entry_uri}/#{target_encoded_entry_uri})
|
103
|
+
end # _generate_cp_or_mv_opstr
|
104
|
+
|
105
|
+
def _batch_cp_or_mv(command, *op_args)
|
106
|
+
execs = []
|
107
|
+
op_args.each do |e|
|
108
|
+
execs << 'op=' + _generate_cp_or_mv_opstr(command, e[0], e[1], e[2], e[3]) if e.size == 4
|
109
|
+
end
|
110
|
+
Auth.request Config.settings[:rs_host] + "/batch", execs.join("&"), {:mime => "application/x-www-form-urlencoded" }
|
111
|
+
end # _batch_cp_or_mv
|
112
|
+
end
|
113
|
+
end # module Storage
|
114
|
+
end # module Qiniu
|
data/lib/qiniu/misc.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Qiniu
|
4
|
+
module Misc
|
5
|
+
class << self
|
6
|
+
include Utils
|
7
|
+
|
8
|
+
def set_protected(bucket, protected_mode)
|
9
|
+
host = Config.settings[:pub_host]
|
10
|
+
Auth.request %Q(#{host}/accessMode/#{bucket}/mode/#{protected_mode})
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_separator(bucket, separator)
|
14
|
+
host = Config.settings[:pub_host]
|
15
|
+
encoded_separator = Utils.urlsafe_base64_encode(separator)
|
16
|
+
Auth.request %Q(#{host}/separator/#{bucket}/sep/#{encoded_separator})
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_style(bucket, name, style)
|
20
|
+
host = Config.settings[:pub_host]
|
21
|
+
encoded_name = Utils.urlsafe_base64_encode(name)
|
22
|
+
encoded_style = Utils.urlsafe_base64_encode(style)
|
23
|
+
Auth.request %Q(#{host}/style/#{bucket}/name/#{encoded_name}/style/#{encoded_style})
|
24
|
+
end
|
25
|
+
|
26
|
+
def unset_style(bucket, name)
|
27
|
+
host = Config.settings[:pub_host]
|
28
|
+
encoded_name = Utils.urlsafe_base64_encode(name)
|
29
|
+
Auth.request %Q(#{host}/unstyle/#{bucket}/name/#{encoded_name})
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end # module Misc
|
34
|
+
end # module Qiniu
|
35
|
+
|
@@ -0,0 +1,306 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'zlib'
|
4
|
+
require 'yaml'
|
5
|
+
require 'tmpdir'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'mime/types'
|
8
|
+
require 'digest/sha1'
|
9
|
+
require 'qiniu/abstract'
|
10
|
+
require 'qiniu/exceptions'
|
11
|
+
|
12
|
+
module Qiniu
|
13
|
+
module Storage
|
14
|
+
|
15
|
+
module AbstractClass
|
16
|
+
class ChunkProgressNotifier
|
17
|
+
include Qiniu::Abstract
|
18
|
+
abstract_methods :notify
|
19
|
+
# def notify(block_index, block_put_progress); end
|
20
|
+
end
|
21
|
+
|
22
|
+
class BlockProgressNotifier
|
23
|
+
include Qiniu::Abstract
|
24
|
+
abstract_methods :notify
|
25
|
+
# def notify(block_index, checksum); end
|
26
|
+
end
|
27
|
+
end # module AbstractClass
|
28
|
+
|
29
|
+
class ChunkProgressNotifier < AbstractClass::ChunkProgressNotifier
|
30
|
+
def notify(index, progress)
|
31
|
+
logmsg = "chunk #{progress[:offset]/Config.settings[:chunk_size]} in block #{index} successfully uploaded.\n" + progress.to_s
|
32
|
+
Utils.debug(logmsg)
|
33
|
+
end
|
34
|
+
end # class ChunkProgressNotifier
|
35
|
+
|
36
|
+
class BlockProgressNotifier < AbstractClass::BlockProgressNotifier
|
37
|
+
def notify(index, checksum)
|
38
|
+
Utils.debug "block #{index}: {ctx: #{checksum}} successfully uploaded."
|
39
|
+
Utils.debug "block #{index}: {checksum: #{checksum}} successfully uploaded."
|
40
|
+
end
|
41
|
+
end # class BlockProgressNotifier
|
42
|
+
|
43
|
+
class << self
|
44
|
+
include Utils
|
45
|
+
|
46
|
+
def resumable_upload_with_token(uptoken,
|
47
|
+
local_file,
|
48
|
+
bucket,
|
49
|
+
key = nil,
|
50
|
+
mime_type = nil,
|
51
|
+
custom_meta = nil,
|
52
|
+
customer = nil,
|
53
|
+
callback_params = nil,
|
54
|
+
rotate = nil)
|
55
|
+
begin
|
56
|
+
ifile = File.open(local_file, 'rb')
|
57
|
+
fh = FileData.new(ifile)
|
58
|
+
fsize = fh.data_size
|
59
|
+
key = Digest::SHA1.hexdigest(local_file + fh.mtime.to_s) if key.nil?
|
60
|
+
if mime_type.nil? || mime_type.empty?
|
61
|
+
mime = MIME::Types.type_for local_file
|
62
|
+
mime_type = mime.empty? ? 'application/octet-stream' : mime[0].content_type
|
63
|
+
end
|
64
|
+
code, data = _resumable_upload(uptoken, fh, fsize, bucket, key, mime_type, custom_meta, customer, callback_params, rotate)
|
65
|
+
[code, data]
|
66
|
+
ensure
|
67
|
+
ifile.close unless ifile.nil?
|
68
|
+
end
|
69
|
+
end # resumable_upload_with_token
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
class FileData
|
74
|
+
attr_accessor :fh
|
75
|
+
def initialize(fh)
|
76
|
+
@fh = fh
|
77
|
+
end
|
78
|
+
def data_size
|
79
|
+
@fh.stat.size
|
80
|
+
end
|
81
|
+
def get_data(offset, length)
|
82
|
+
@fh.seek(offset)
|
83
|
+
@fh.read(length)
|
84
|
+
end
|
85
|
+
def path
|
86
|
+
@fh.path
|
87
|
+
end
|
88
|
+
def mtime
|
89
|
+
@fh.mtime
|
90
|
+
end
|
91
|
+
#delegate :path, :mtime, :to => :fh
|
92
|
+
end # class FileData
|
93
|
+
|
94
|
+
def _new_block_put_progress_data
|
95
|
+
{:ctx => nil, :offset => 0, :restsize => nil, :status_code => nil, :host => nil}
|
96
|
+
end # _new_block_put_progress_data
|
97
|
+
|
98
|
+
def _call_binary_with_token(uptoken, url, data, content_type = nil, retry_times = 0)
|
99
|
+
options = {
|
100
|
+
:method => :post,
|
101
|
+
:content_type => 'application/octet-stream',
|
102
|
+
:upload_signature_token => uptoken
|
103
|
+
}
|
104
|
+
options[:content_type] = content_type if !content_type.nil? && !content_type.empty?
|
105
|
+
code, data = http_request url, data, options
|
106
|
+
unless Utils.is_response_ok?(code)
|
107
|
+
retry_times += 1
|
108
|
+
if Config.settings[:auto_reconnect] && retry_times < Config.settings[:max_retry_times]
|
109
|
+
return _call_binary_with_token(uptoken, url, data, options[:content_type], retry_times)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
[code, data]
|
113
|
+
end # _call_binary_with_token
|
114
|
+
|
115
|
+
def _mkblock(uptoken, block_size, body)
|
116
|
+
url = Config.settings[:up_host] + "/mkblk/#{block_size}"
|
117
|
+
_call_binary_with_token(uptoken, url, body)
|
118
|
+
end # _mkblock
|
119
|
+
|
120
|
+
def _putblock(uphost, uptoken, ctx, offset, body)
|
121
|
+
url = uphost + "/bput/#{ctx}/#{offset}"
|
122
|
+
_call_binary_with_token(uptoken, url, body)
|
123
|
+
end # _putblock
|
124
|
+
|
125
|
+
def _resumable_put_block(uptoken,
|
126
|
+
fh,
|
127
|
+
block_index,
|
128
|
+
block_size,
|
129
|
+
chunk_size,
|
130
|
+
progress,
|
131
|
+
retry_times,
|
132
|
+
notifier)
|
133
|
+
code, data = 0, {}
|
134
|
+
fpath = fh.path
|
135
|
+
|
136
|
+
# this block has never been uploaded.
|
137
|
+
if progress[:ctx] == nil || progress[:ctx].empty?
|
138
|
+
progress[:offset] = 0
|
139
|
+
progress[:restsize] = block_size
|
140
|
+
# choose the smaller one
|
141
|
+
body_length = [block_size, chunk_size].min
|
142
|
+
for i in 1..retry_times
|
143
|
+
seek_pos = block_index*Config.settings[:block_size]
|
144
|
+
body = fh.get_data(seek_pos, body_length)
|
145
|
+
result_length = body.length
|
146
|
+
if result_length != body_length
|
147
|
+
raise FileSeekReadError.new(fpath, block_index, seek_pos, body_length, result_length)
|
148
|
+
end
|
149
|
+
code, data = _mkblock(uptoken, block_size, body)
|
150
|
+
body_crc32 = Zlib.crc32(body)
|
151
|
+
if Utils.is_response_ok?(code) && data["crc32"] == body_crc32
|
152
|
+
progress[:ctx] = data["ctx"]
|
153
|
+
progress[:offset] = body_length
|
154
|
+
progress[:restsize] = block_size - body_length
|
155
|
+
progress[:status_code] = code
|
156
|
+
progress[:host] = data["host"]
|
157
|
+
if !notifier.nil? && notifier.respond_to?("notify")
|
158
|
+
notifier.notify(block_index, progress)
|
159
|
+
end
|
160
|
+
break
|
161
|
+
elsif i == retry_times && data["crc32"] != body_crc32
|
162
|
+
Log.logger.error %Q(Uploading block error. Expected crc32: #{body_crc32}, but got: #{data["crc32"]})
|
163
|
+
end
|
164
|
+
end
|
165
|
+
elsif progress[:offset] + progress[:restsize] != block_size
|
166
|
+
raise BlockSizeNotMathchError.new(fpath, block_index, progress[:offset], progress[:restsize], block_size)
|
167
|
+
end
|
168
|
+
|
169
|
+
# loop uploading other chunks except the first one
|
170
|
+
while progress[:restsize].to_i > 0 && progress[:restsize] < block_size
|
171
|
+
# choose the smaller one
|
172
|
+
body_length = [progress[:restsize], chunk_size].min
|
173
|
+
for i in 1..retry_times
|
174
|
+
seek_pos = block_index*Config.settings[:block_size] + progress[:offset]
|
175
|
+
body = fh.get_data(seek_pos, body_length)
|
176
|
+
result_length = body.length
|
177
|
+
if result_length != body_length
|
178
|
+
raise FileSeekReadError.new(fpath, block_index, seek_pos, body_length, result_length)
|
179
|
+
end
|
180
|
+
code, data = _putblock(progress[:host], uptoken, progress[:ctx], progress[:offset], body)
|
181
|
+
body_crc32 = Zlib.crc32(body)
|
182
|
+
if Utils.is_response_ok?(code) && data["crc32"] == body_crc32
|
183
|
+
progress[:ctx] = data["ctx"]
|
184
|
+
progress[:offset] += body_length
|
185
|
+
progress[:restsize] -= body_length
|
186
|
+
progress[:status_code] = code
|
187
|
+
progress[:host] = data["host"]
|
188
|
+
if !notifier.nil? && notifier.respond_to?("notify")
|
189
|
+
notifier.notify(block_index, progress)
|
190
|
+
end
|
191
|
+
break
|
192
|
+
elsif i == retry_times && data["crc32"] != body_crc32
|
193
|
+
Log.logger.error %Q(Uploading block error. Expected crc32: #{body_crc32}, but got: #{data["crc32"]})
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
# return
|
198
|
+
return [code, data]
|
199
|
+
end # _resumable_put_block
|
200
|
+
|
201
|
+
def _block_count(fsize)
|
202
|
+
((fsize + Config.settings[:block_size] - 1) / Config.settings[:block_size]).to_i
|
203
|
+
end # _block_count
|
204
|
+
|
205
|
+
def _resumable_put(uptoken,
|
206
|
+
fh,
|
207
|
+
checksums,
|
208
|
+
progresses,
|
209
|
+
block_notifier = nil,
|
210
|
+
chunk_notifier = nil)
|
211
|
+
code, data = 0, {}
|
212
|
+
fsize = fh.data_size
|
213
|
+
block_count = _block_count(fsize)
|
214
|
+
checksum_count = checksums.length
|
215
|
+
progress_count = progresses.length
|
216
|
+
if checksum_count != block_count || progress_count != block_count
|
217
|
+
raise BlockCountNotMathchError.new(fh.path, block_count, checksum_count, progress_count)
|
218
|
+
end
|
219
|
+
0.upto(block_count-1).each do |block_index|
|
220
|
+
if checksums[block_index].nil? || checksums[block_index].empty?
|
221
|
+
block_size = Config.settings[:block_size]
|
222
|
+
if block_index == block_count - 1
|
223
|
+
block_size = fsize - block_index*Config.settings[:block_size]
|
224
|
+
end
|
225
|
+
if progresses[block_index].nil?
|
226
|
+
progresses[block_index] = _new_block_put_progress_data
|
227
|
+
end
|
228
|
+
#code, data = _resumable_put_block(uptoken, fh, block_index, block_size, Config.settings[:chunk_size], progresses[block_index], Config.settings[:max_retry_times], chunk_notifier)
|
229
|
+
# Put the whole block as a chunk
|
230
|
+
code, data = _resumable_put_block(uptoken, fh, block_index, block_size, block_size, progresses[block_index], Config.settings[:max_retry_times], chunk_notifier)
|
231
|
+
if Utils.is_response_ok?(code)
|
232
|
+
#checksums[block_index] = data["checksum"]
|
233
|
+
checksums[block_index] = data["ctx"]
|
234
|
+
if !block_notifier.nil? && block_notifier.respond_to?("notify")
|
235
|
+
block_notifier.notify(block_index, checksums[block_index])
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
return [code, data]
|
241
|
+
end # _resumable_put
|
242
|
+
|
243
|
+
def _mkfile(uphost,
|
244
|
+
uptoken,
|
245
|
+
entry_uri,
|
246
|
+
fsize,
|
247
|
+
checksums,
|
248
|
+
mime_type = nil,
|
249
|
+
custom_meta = nil,
|
250
|
+
customer = nil,
|
251
|
+
callback_params = nil,
|
252
|
+
rotate = nil)
|
253
|
+
path = '/rs-mkfile/' + Utils.urlsafe_base64_encode(entry_uri) + "/fsize/#{fsize}"
|
254
|
+
path += '/mimeType/' + Utils.urlsafe_base64_encode(mime_type) if !mime_type.nil? && !mime_type.empty?
|
255
|
+
path += '/meta/' + Utils.urlsafe_base64_encode(custom_meta) if !custom_meta.nil? && !custom_meta.empty?
|
256
|
+
path += '/customer/' + customer if !customer.nil? && !customer.empty?
|
257
|
+
callback_query_string = Utils.generate_query_string(callback_params) if !callback_params.nil? && !callback_params.empty?
|
258
|
+
path += '/params/' + Utils.urlsafe_base64_encode(callback_query_string) if !callback_query_string.nil? && !callback_query_string.empty?
|
259
|
+
path += '/rotate/' + rotate if !rotate.nil? && rotate.to_i >= 0
|
260
|
+
url = uphost + path
|
261
|
+
#body = ''
|
262
|
+
#checksums.each do |checksum|
|
263
|
+
# body += Utils.urlsafe_base64_decode(checksum)
|
264
|
+
#end
|
265
|
+
body = checksums.join(',')
|
266
|
+
_call_binary_with_token(uptoken, url, body, 'text/plain')
|
267
|
+
end # _mkfile
|
268
|
+
|
269
|
+
def _resumable_upload(uptoken,
|
270
|
+
fh,
|
271
|
+
fsize,
|
272
|
+
bucket,
|
273
|
+
key,
|
274
|
+
mime_type = nil,
|
275
|
+
custom_meta = nil,
|
276
|
+
customer = nil,
|
277
|
+
callback_params = nil,
|
278
|
+
rotate = nil)
|
279
|
+
|
280
|
+
block_count = _block_count(fsize)
|
281
|
+
|
282
|
+
chunk_notifier = ChunkProgressNotifier.new()
|
283
|
+
block_notifier = BlockProgressNotifier.new()
|
284
|
+
|
285
|
+
progresses = []
|
286
|
+
block_count.times{progresses << _new_block_put_progress_data}
|
287
|
+
checksums = []
|
288
|
+
block_count.times{checksums << ''}
|
289
|
+
|
290
|
+
code, data = _resumable_put(uptoken, fh, checksums, progresses, block_notifier, chunk_notifier)
|
291
|
+
|
292
|
+
if Utils.is_response_ok?(code)
|
293
|
+
uphost = data["host"]
|
294
|
+
entry_uri = bucket + ':' + key
|
295
|
+
code, data = _mkfile(uphost, uptoken, entry_uri, fsize, checksums, mime_type, custom_meta, customer, callback_params, rotate)
|
296
|
+
end
|
297
|
+
|
298
|
+
if Utils.is_response_ok?(code)
|
299
|
+
Utils.debug "File #{fh.path} {size: #{fsize}} successfully uploaded."
|
300
|
+
end
|
301
|
+
|
302
|
+
[code, data]
|
303
|
+
end # _resumable_upload
|
304
|
+
end # self class
|
305
|
+
end # module Storage
|
306
|
+
end # module Qiniu
|