swift_client 0.0.1 → 0.0.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.
- data/lib/swift_client/version.rb +1 -1
- data/lib/swift_client.rb +52 -34
- data/test/swift_client_test.rb +18 -1
- metadata +1 -1
data/lib/swift_client/version.rb
CHANGED
data/lib/swift_client.rb
CHANGED
@@ -3,11 +3,13 @@ require "swift_client/version"
|
|
3
3
|
|
4
4
|
require "httparty"
|
5
5
|
require "mime-types"
|
6
|
+
require "openssl"
|
6
7
|
|
7
8
|
class SwiftClient
|
8
9
|
class AuthenticationError < StandardError; end
|
9
10
|
class OptionError < StandardError; end
|
10
11
|
class EmptyNameError < StandardError; end
|
12
|
+
class TempUrlKeyMissing < StandardError; end
|
11
13
|
|
12
14
|
class ResponseError < StandardError
|
13
15
|
attr_accessor :code, :message
|
@@ -38,69 +40,69 @@ class SwiftClient
|
|
38
40
|
request :get, "/", :query => query
|
39
41
|
end
|
40
42
|
|
41
|
-
def get_container(
|
42
|
-
raise(EmptyNameError) if
|
43
|
+
def get_container(container, query = {})
|
44
|
+
raise(EmptyNameError) if container.empty?
|
43
45
|
|
44
|
-
request :get, "/#{
|
46
|
+
request :get, "/#{container}", :query => query
|
45
47
|
end
|
46
48
|
|
47
|
-
def head_container(
|
48
|
-
raise(EmptyNameError) if
|
49
|
+
def head_container(container)
|
50
|
+
raise(EmptyNameError) if container.empty?
|
49
51
|
|
50
|
-
request :head, "/#{
|
52
|
+
request :head, "/#{container}"
|
51
53
|
end
|
52
54
|
|
53
|
-
def put_container(
|
54
|
-
raise(EmptyNameError) if
|
55
|
+
def put_container(container, headers = {})
|
56
|
+
raise(EmptyNameError) if container.empty?
|
55
57
|
|
56
|
-
request :put, "/#{
|
58
|
+
request :put, "/#{container}", :headers => headers
|
57
59
|
end
|
58
60
|
|
59
|
-
def post_container(
|
60
|
-
raise(EmptyNameError) if
|
61
|
+
def post_container(container, headers = {})
|
62
|
+
raise(EmptyNameError) if container.empty?
|
61
63
|
|
62
|
-
request :post, "/#{
|
64
|
+
request :post, "/#{container}", :headers => headers
|
63
65
|
end
|
64
66
|
|
65
|
-
def delete_container(
|
66
|
-
raise(EmptyNameError) if
|
67
|
+
def delete_container(container)
|
68
|
+
raise(EmptyNameError) if container.empty?
|
67
69
|
|
68
|
-
request :delete, "/#{
|
70
|
+
request :delete, "/#{container}"
|
69
71
|
end
|
70
72
|
|
71
|
-
def put_object(
|
72
|
-
raise(EmptyNameError) if
|
73
|
+
def put_object(object, data_or_io, container, headers = {})
|
74
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
73
75
|
|
74
|
-
mime_type = MIME::Types.of(
|
76
|
+
mime_type = MIME::Types.of(object).first
|
75
77
|
|
76
78
|
extended_headers = headers.dup
|
77
79
|
extended_headers["Content-Type"] ||= mime_type.content_type if mime_type
|
78
80
|
|
79
|
-
request :put, "/#{container}/#{
|
81
|
+
request :put, "/#{container}/#{object}", :body => data_or_io.respond_to?(:read) ? data_or_io.read : data_or_io, :headers => extended_headers
|
80
82
|
end
|
81
83
|
|
82
|
-
def post_object(
|
83
|
-
raise(EmptyNameError) if
|
84
|
+
def post_object(object, container, headers = {})
|
85
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
84
86
|
|
85
|
-
request :post, "/#{container}/#{
|
87
|
+
request :post, "/#{container}/#{object}", :headers => headers
|
86
88
|
end
|
87
89
|
|
88
|
-
def get_object(
|
89
|
-
raise(EmptyNameError) if
|
90
|
+
def get_object(object, container)
|
91
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
90
92
|
|
91
|
-
request :get, "/#{container}/#{
|
93
|
+
request :get, "/#{container}/#{object}"
|
92
94
|
end
|
93
95
|
|
94
|
-
def head_object(
|
95
|
-
raise(EmptyNameError) if
|
96
|
+
def head_object(object, container)
|
97
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
96
98
|
|
97
|
-
request :head, "/#{container}/#{
|
99
|
+
request :head, "/#{container}/#{object}"
|
98
100
|
end
|
99
101
|
|
100
|
-
def delete_object(
|
101
|
-
raise(EmptyNameError) if
|
102
|
+
def delete_object(object, container)
|
103
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
102
104
|
|
103
|
-
request :delete, "/#{container}/#{
|
105
|
+
request :delete, "/#{container}/#{object}"
|
104
106
|
end
|
105
107
|
|
106
108
|
def get_objects(container, query = {})
|
@@ -109,6 +111,24 @@ class SwiftClient
|
|
109
111
|
request :get, "/#{container}", :query => query
|
110
112
|
end
|
111
113
|
|
114
|
+
def public_url(object, container)
|
115
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
116
|
+
|
117
|
+
"#{storage_url}/#{container}/#{object}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def temp_url(object, container, opts = {})
|
121
|
+
raise(EmptyNameError) if object.empty? || container.empty?
|
122
|
+
raise(TempUrlKeyMissing) unless options[:temp_url_key]
|
123
|
+
|
124
|
+
expires = (Time.now + (options[:expires_in] || 3600).to_i).to_i
|
125
|
+
path = "/#{container}/#{object}"
|
126
|
+
|
127
|
+
signature = OpenSSL::HMAC.hexdigest("sha1", options[:temp_url_key], "GET\n#{expires}\n#{path}")
|
128
|
+
|
129
|
+
"#{storage_url}#{path}?temp_url_sig=#{signature}&temp_url_expires=#{expires}"
|
130
|
+
end
|
131
|
+
|
112
132
|
private
|
113
133
|
|
114
134
|
def request(method, path, opts = {})
|
@@ -135,9 +155,7 @@ class SwiftClient
|
|
135
155
|
raise(AuthenticationError, "#{response.code}: #{response.message}") unless response.success?
|
136
156
|
|
137
157
|
self.auth_token = response.headers["X-Auth-Token"]
|
138
|
-
self.storage_url = response.headers["X-Storage-Url"]
|
139
|
-
|
140
|
-
storage_url.gsub!(/^http:/, "https:") if options[:auth_url] =~ /^https:/
|
158
|
+
self.storage_url = options[:storage_url] || response.headers["X-Storage-Url"]
|
141
159
|
end
|
142
160
|
end
|
143
161
|
|
data/test/swift_client_test.rb
CHANGED
@@ -5,12 +5,21 @@ class SwiftClientTest < MiniTest::Test
|
|
5
5
|
def setup
|
6
6
|
stub_request(:get, "https://example.com/auth/v1.0").with(:headers => { "X-Auth-Key" => "secret", "X-Auth-User" => "account:username" }).to_return(:status => 200, :body => "", :headers => { "X-Auth-Token" => "Token", "X-Storage-Url" => "https://example.com/v1/AUTH_account" })
|
7
7
|
|
8
|
-
@swift_client = SwiftClient.new(:auth_url => "https://example.com/auth/v1.0", :username => "account:username", :api_key => "secret")
|
8
|
+
@swift_client = SwiftClient.new(:auth_url => "https://example.com/auth/v1.0", :username => "account:username", :api_key => "secret", :temp_url_key => "Temp url key")
|
9
9
|
|
10
10
|
assert_equal "Token", @swift_client.auth_token
|
11
11
|
assert_equal "https://example.com/v1/AUTH_account", @swift_client.storage_url
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_storage_url
|
15
|
+
stub_request(:get, "https://example.com/auth/v1.0").with(:headers => { "X-Auth-Key" => "secret", "X-Auth-User" => "account:username" }).to_return(:status => 200, :body => "", :headers => { "X-Auth-Token" => "Token", "X-Storage-Url" => "https://example.com/v1/AUTH_account" })
|
16
|
+
|
17
|
+
@swift_client = SwiftClient.new(:auth_url => "https://example.com/auth/v1.0", :username => "account:username", :api_key => "secret", :storage_url => "https://storage-url.com/path")
|
18
|
+
|
19
|
+
assert_equal "Token", @swift_client.auth_token
|
20
|
+
assert_equal "https://storage-url.com/path", @swift_client.storage_url
|
21
|
+
end
|
22
|
+
|
14
23
|
def test_get_containers
|
15
24
|
containers = [
|
16
25
|
{ "count" => 1, "bytes" => 1, "name" => "container-1" },
|
@@ -114,5 +123,13 @@ class SwiftClientTest < MiniTest::Test
|
|
114
123
|
assert_equal "Not Found", e.message
|
115
124
|
end
|
116
125
|
end
|
126
|
+
|
127
|
+
def test_public_url
|
128
|
+
assert_equal "https://example.com/v1/AUTH_account/container/object", @swift_client.public_url("object", "container")
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_temp_url
|
132
|
+
assert @swift_client.temp_url("object", "container", :expires_in => 3600) =~ %r{https://example.com/v1/AUTH_account/container/object\?temp_url_sig=[a-f0-9]{40}&temp_url_expires=[0-9]+}
|
133
|
+
end
|
117
134
|
end
|
118
135
|
|