qiniu-s3 0.1.2

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.
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'mime/types'
4
+ require 'digest/sha1'
5
+ require 'qiniu/s3/exceptions'
6
+
7
+ module Qiniu
8
+ module S3
9
+ module IO
10
+ class << self
11
+ include Utils
12
+
13
+ def put_auth(expires_in = nil, callback_url = nil)
14
+ url = Config.settings[:io_host] + "/put-auth/"
15
+ url += "#{expires_in}" if !expires_in.nil? && expires_in > 0
16
+ if !callback_url.nil? && !callback_url.empty?
17
+ encoded_callback_url = Utils.urlsafe_base64_encode(callback_url)
18
+ url += "/callback/#{encoded_callback_url}"
19
+ end
20
+ Auth.request(url)
21
+ end
22
+
23
+ def put_file(url, local_file, bucket = '', key = '', mime_type = '', custom_meta = '', callback_params = '')
24
+ raise NoSuchFileError unless File.exist?(local_file)
25
+ key = Digest::SHA1.hexdigest(local_file + Time.now.to_s) if key.empty?
26
+ entry_uri = bucket + ':' + key
27
+ if mime_type.empty?
28
+ mime = MIME::Types.type_for local_file
29
+ mime_type = mime.empty? ? 'application/octet-stream' : mime[0].content_type
30
+ end
31
+ action_params = '/rs-put/' + Utils.urlsafe_base64_encode(entry_uri) + '/mimeType/' + Utils.urlsafe_base64_encode(mime_type)
32
+ action_params += '/meta/' + Utils.urlsafe_base64_encode(custom_meta) unless custom_meta.empty?
33
+ callback_params = {:bucket => bucket, :key => key, :mime_type => mime_type} if callback_params.empty?
34
+ callback_query_string = Utils.generate_query_string(callback_params)
35
+ Utils.upload_multipart_data(url, local_file, action_params, callback_query_string)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'logger'
4
+
5
+ module Qiniu
6
+ module S3
7
+ module Log
8
+ class << self
9
+ attr_accessor :logger
10
+
11
+ def logger
12
+ @logger ||= Logger.new(STDERR)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,63 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Qiniu
4
+ module S3
5
+ module RS
6
+ class << self
7
+ include Utils
8
+
9
+ def stat(bucket, key)
10
+ Auth.request Config.settings[:rs_host] + '/stat/' + encode_entry_uri(bucket, key)
11
+ end
12
+
13
+ def get(bucket, key, save_as = nil, expires_in = nil, version = nil)
14
+ url = Config.settings[:rs_host] + '/get/' + encode_entry_uri(bucket, key)
15
+ url += '/base/' + version unless version.nil?
16
+ url += '/attName/' + Utils.urlsafe_base64_encode(save_as) unless save_as.nil?
17
+ url += '/expires/' + expires_in.to_s if !expires_in.nil? && expires_in > 0
18
+ Auth.request url
19
+ end
20
+
21
+ def delete(bucket, key)
22
+ Auth.request Config.settings[:rs_host] + '/delete/' + encode_entry_uri(bucket, key)
23
+ end
24
+
25
+ def publish(domain, bucket)
26
+ encoded_domain = Utils.urlsafe_base64_encode(domain)
27
+ Auth.request Config.settings[:rs_host] + "/publish/#{encoded_domain}/from/#{bucket}"
28
+ end
29
+
30
+ def unpublish(domain)
31
+ encoded_domain = Utils.urlsafe_base64_encode(domain)
32
+ Auth.request Config.settings[:rs_host] + "/unpublish/#{encoded_domain}"
33
+ end
34
+
35
+ def drop(bucket)
36
+ Auth.request Config.settings[:rs_host] + "/drop/#{bucket}"
37
+ end
38
+
39
+ def batch(command, bucket, keys)
40
+ execs = []
41
+ keys.each do |key|
42
+ encoded_uri = encode_entry_uri(bucket, key)
43
+ execs << "op=/#{command}/#{encoded_uri}"
44
+ end
45
+ Auth.request Config.settings[:rs_host] + "/batch?" + execs.join("&")
46
+ end
47
+
48
+ def batch_get(bucket, keys)
49
+ batch("get", bucket, keys)
50
+ end
51
+
52
+ def batch_stat(bucket, keys)
53
+ batch("stat", bucket, keys)
54
+ end
55
+
56
+ def batch_delete(bucket, keys)
57
+ batch("delete", bucket, keys)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,124 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'uri'
4
+ require 'json'
5
+ require 'base64'
6
+ require 'rest_client'
7
+ require 'qiniu/s3/exceptions'
8
+
9
+ module Qiniu
10
+ module S3
11
+ module Utils extend self
12
+
13
+ def urlsafe_base64_encode content
14
+ Base64.encode64(content).strip.gsub('+', '-').gsub('/','_').gsub(/\r?\n/, '')
15
+ end
16
+
17
+ def urlsafe_base64_decode encoded_content
18
+ Base64.decode64 encoded_content.gsub('_','/').gsub('-', '+')
19
+ end
20
+
21
+ def encode_entry_uri(bucket, key)
22
+ entry_uri = bucket + ':' + key
23
+ urlsafe_base64_encode(entry_uri)
24
+ end
25
+
26
+ def safe_json_parse(data)
27
+ JSON.parse(data)
28
+ rescue JSON::ParserError
29
+ {}
30
+ end
31
+
32
+ def send_request_with url, data = nil, options = {}
33
+ options[:method] = Config.settings[:method] unless options[:method]
34
+ options[:content_type] = Config.settings[:content_type] unless options[:content_type]
35
+ header_options = {
36
+ :accept => :json,
37
+ :user_agent => Config.settings[:user_agent]
38
+ }
39
+ header_options.merge!('Authorization' => "Bearer #{options[:access_token]}") if options[:access_token]
40
+ case options[:method]
41
+ when :get
42
+ response = RestClient.get url, header_options
43
+ when :post
44
+ header_options.merge!(:content_type => options[:content_type])
45
+ response = RestClient.post url, data, header_options
46
+ end
47
+ code = response.respond_to?(:code) ? response.code.to_i : 0
48
+ if code != 200
49
+ raise RequestFailed.new(response)
50
+ else
51
+ data = {}
52
+ body = response.respond_to?(:body) ? response.body : {}
53
+ data = safe_json_parse(body) unless body.empty?
54
+ end
55
+ [code, data]
56
+ end
57
+
58
+ def http_request url, data = nil, options = {}
59
+ retry_times = 0
60
+ begin
61
+ retry_times += 1
62
+ send_request_with url, data, options
63
+ rescue Errno::ECONNRESET => err
64
+ if Config.settings[:auto_reconnect] && retry_times < Config.settings[:max_retry_times]
65
+ retry
66
+ else
67
+ Log.logger.error err
68
+ end
69
+ rescue => e
70
+ Log.logger.warn "#{e.message} => Utils.http_request('#{url}')"
71
+ code = 0
72
+ data = {}
73
+ body = {}
74
+ if e.respond_to? :response
75
+ res = e.response
76
+ code = res.code.to_i if res.respond_to? :code
77
+ body = res.respond_to?(:body) ? res.body : ""
78
+ data = safe_json_parse(body) unless body.empty?
79
+ end
80
+ [code, data]
81
+ end
82
+ end
83
+
84
+ def upload_multipart_data(url, filepath, action_string, callback_query_string = '')
85
+ code, data = 0, {}
86
+ begin
87
+ header_options = {
88
+ :accept => :json,
89
+ :user_agent => Config.settings[:user_agent]
90
+ }
91
+ post_data = {
92
+ :file => File.new(filepath, 'rb'),
93
+ :params => callback_query_string,
94
+ :action => action_string,
95
+ :multipart => true
96
+ }
97
+ response = RestClient.post url, post_data, header_options
98
+ body = response.respond_to?(:body) ? response.body : ""
99
+ data = safe_json_parse(body) unless body.empty?
100
+ code = response.code.to_i if response.respond_to?(:code)
101
+ rescue Errno::ECONNRESET => err
102
+ Log.logger.error err
103
+ rescue => e
104
+ Log.logger.warn "#{e.message} => Utils.http_request('#{url}')"
105
+ res = e.response
106
+ if e.respond_to? :response
107
+ res = e.response
108
+ code = res.code.to_i if res.respond_to? :code
109
+ body = res.respond_to?(:body) ? res.body : ""
110
+ data = safe_json_parse(body) unless body.empty?
111
+ end
112
+ end
113
+ [code, data]
114
+ end
115
+
116
+ def generate_query_string(params)
117
+ return params if params.is_a?(String)
118
+ total_param = params.map { |key, value| key.to_s+"="+value.to_s }
119
+ URI.escape(total_param.join("&"))
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Qiniu
4
+ module S3
5
+ VERSION = "0.1.2"
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/qiniu/s3/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["why404"]
7
+ gem.email = ["why404@gmail.com"]
8
+ gem.description = %q{Qiniu Cloud Storage SDK for Ruby. See: http://docs.qiniutek.com/v1/sdk/ruby/}
9
+ gem.summary = %q{Qiniu Cloud Storage SDK for Ruby}
10
+ gem.homepage = "https://github.com/why404/qiniu-s3-sdk-for-ruby"
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "qiniu-s3"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Qiniu::S3::VERSION
18
+
19
+ # specify any dependencies here; for example:
20
+ gem.add_development_dependency "rspec"
21
+ gem.add_development_dependency "fakeweb"
22
+ gem.add_runtime_dependency "rest-client"
23
+ gem.add_runtime_dependency "mime-types"
24
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+ require 'qiniu/s3/auth'
5
+
6
+ module Qiniu
7
+ module S3
8
+ describe Auth do
9
+
10
+ before :all do
11
+ @username = "test@qbox.net"
12
+ @password = "test"
13
+
14
+ code, data = Qiniu::S3::Auth.exchange_by_password!(@username, @password)
15
+ code.should == 200
16
+ data.should be_an_instance_of(Hash)
17
+ data["access_token"].should_not be_empty
18
+ data["refresh_token"].should_not be_empty
19
+ data["refresh_token"].should_not be_empty
20
+
21
+ @access_token = data["access_token"]
22
+ @refresh_token = data["refresh_token"]
23
+ puts data.inspect
24
+ end
25
+
26
+ context ".exchange_by_password" do
27
+ it "should sign in failed when pass a non-existent username" do
28
+ code, data = Qiniu::S3::Auth.exchange_by_password!("a_non_existent_user@example.com", "password")
29
+ code.should == 401
30
+ data["error_code"].should == 11
31
+ data["error"].should == "failed_authentication"
32
+ puts data.inspect
33
+ end
34
+
35
+ it "should sign in failed when pass a wrong password" do
36
+ code, data = Qiniu::S3::Auth.exchange_by_password!(@username, "a-wrong-password")
37
+ code.should == 401
38
+ data["error_code"].should == 11
39
+ data["error"].should == "failed_authentication"
40
+ puts data.inspect
41
+ end
42
+ end
43
+
44
+ context ".exchange_by_refresh_token" do
45
+ it "should works" do
46
+ @refresh_token.should_not be_empty
47
+ code, data = Qiniu::S3::Auth.exchange_by_refresh_token!(@refresh_token)
48
+ code.should == 200
49
+ data["access_token"].should_not be_empty
50
+ data["refresh_token"].should_not be_empty
51
+ data["expires_in"].should_not be_zero
52
+ puts data.inspect
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+ require 'qiniu/s3/auth'
5
+ require 'qiniu/s3/rs'
6
+ require 'qiniu/s3/image'
7
+
8
+ module Qiniu
9
+ module S3
10
+ describe Image do
11
+
12
+ before :all do
13
+ code, data = Qiniu::S3::Auth.exchange_by_password!("test@qbox.net", "test")
14
+ code.should == 200
15
+ data.should be_an_instance_of(Hash)
16
+ data["access_token"].should_not be_empty
17
+ data["refresh_token"].should_not be_empty
18
+ data["refresh_token"].should_not be_empty
19
+ puts data.inspect
20
+
21
+ @bucket = "test_images"
22
+ @key = "test_image.jpg"
23
+ code2, data2 = Qiniu::S3::RS.get(@bucket, @key)
24
+ code2.should == 200
25
+ data2["url"].should_not be_empty
26
+ puts data2.inspect
27
+
28
+ @download_url = data2["url"]
29
+ end
30
+
31
+ context ".info" do
32
+ it "should works" do
33
+ code, data = Qiniu::S3::Image.info(@download_url)
34
+ code.should == 200
35
+ puts data.inspect
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+ require 'qiniu/s3/auth'
5
+ require 'qiniu/s3/io'
6
+ require 'digest/sha1'
7
+
8
+ module Qiniu
9
+ module S3
10
+ describe IO do
11
+
12
+ before :all do
13
+ code, data = Qiniu::S3::Auth.exchange_by_password!("test@qbox.net", "test")
14
+ code.should == 200
15
+ data.should be_an_instance_of(Hash)
16
+ data["access_token"].should_not be_empty
17
+ data["refresh_token"].should_not be_empty
18
+ data["refresh_token"].should_not be_empty
19
+ puts data.inspect
20
+
21
+ code2, data2 = Qiniu::S3::IO.put_auth()
22
+ code2.should == 200
23
+ data2["url"].should_not be_empty
24
+ data2["expiresIn"].should_not be_zero
25
+ puts data2.inspect
26
+
27
+ @put_url = data2["url"]
28
+ @bucket = "test"
29
+ @key = Digest::SHA1.hexdigest (Time.now.to_i+rand(100)).to_s
30
+ end
31
+
32
+ context ".put_file" do
33
+ it "should works" do
34
+ code, data = Qiniu::S3::IO.put_file(@put_url, __FILE__, @bucket, @key)
35
+ code.should == 200
36
+ puts data.inspect
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,116 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'digest/sha1'
4
+ require 'spec_helper'
5
+ require 'qiniu/s3/auth'
6
+ require 'qiniu/s3/io'
7
+ require 'qiniu/s3/rs'
8
+
9
+ module Qiniu
10
+ module S3
11
+ describe RS do
12
+
13
+ before :all do
14
+ code, data = Qiniu::S3::Auth.exchange_by_password!("test@qbox.net", "test")
15
+ code.should == 200
16
+ data.should be_an_instance_of(Hash)
17
+ data["access_token"].should_not be_empty
18
+ data["refresh_token"].should_not be_empty
19
+ data["refresh_token"].should_not be_empty
20
+ puts data.inspect
21
+
22
+ code2, data2 = Qiniu::S3::IO.put_auth()
23
+ code2.should == 200
24
+ data2["url"].should_not be_empty
25
+ data2["expiresIn"].should_not be_zero
26
+ puts data2.inspect
27
+
28
+ @put_url = data2["url"]
29
+ @bucket = "test"
30
+ @key = Digest::SHA1.hexdigest (Time.now.to_i+rand(100)).to_s
31
+ @domain = 'cdn.example.com'
32
+ end
33
+
34
+ context "IO.put_file" do
35
+ it "should works" do
36
+ code, data = Qiniu::S3::IO.put_file(@put_url, __FILE__, @bucket, @key)
37
+ code.should == 200
38
+ puts data.inspect
39
+ end
40
+ end
41
+
42
+ context ".stat" do
43
+ it "should works" do
44
+ code, data = Qiniu::S3::RS.stat(@bucket, @key)
45
+ code.should == 200
46
+ puts data.inspect
47
+ end
48
+ end
49
+
50
+ context ".get" do
51
+ it "should works" do
52
+ code, data = Qiniu::S3::RS.get(@bucket, @key, "rs_spec.rb", 1)
53
+ code.should == 200
54
+ puts data.inspect
55
+ end
56
+ end
57
+
58
+ context ".batch" do
59
+ it "should works" do
60
+ code, data = Qiniu::S3::RS.batch("stat", @bucket, [@key])
61
+ code.should == 200
62
+ puts data.inspect
63
+ end
64
+ end
65
+
66
+ context ".batch_stat" do
67
+ it "should works" do
68
+ code, data = Qiniu::S3::RS.batch_stat(@bucket, [@key])
69
+ code.should == 200
70
+ puts data.inspect
71
+ end
72
+ end
73
+
74
+ context ".batch_get" do
75
+ it "should works" do
76
+ code, data = Qiniu::S3::RS.batch_get(@bucket, [@key])
77
+ code.should == 200
78
+ puts data.inspect
79
+ end
80
+ end
81
+
82
+ context ".publish" do
83
+ it "should works" do
84
+ code, data = Qiniu::S3::RS.publish(@domain, @bucket)
85
+ code.should == 200
86
+ puts data.inspect
87
+ end
88
+ end
89
+
90
+ context ".unpublish" do
91
+ it "should works" do
92
+ code, data = Qiniu::S3::RS.unpublish(@domain)
93
+ code.should == 200
94
+ puts data.inspect
95
+ end
96
+ end
97
+
98
+ context ".delete" do
99
+ it "should works" do
100
+ code, data = Qiniu::S3::RS.delete(@bucket, @key)
101
+ code.should == 200
102
+ puts data.inspect
103
+ end
104
+ end
105
+
106
+ context ".drop" do
107
+ it "should works" do
108
+ code, data = Qiniu::S3::RS.drop(@bucket)
109
+ code.should == 200
110
+ puts data.inspect
111
+ end
112
+ end
113
+
114
+ end
115
+ end
116
+ end