ruby-manta 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5526525955be143def0033e1f1e72e5a57fe3aef
4
- data.tar.gz: b4d4c6a1d8976375027b705e1484419cb4a5daf7
3
+ metadata.gz: 4ac1cb7a31f6bd034a46082aa48450086999752e
4
+ data.tar.gz: 6d19bdfbafe9f4a3ccaf820fb4bcbf246aa9cc99
5
5
  SHA512:
6
- metadata.gz: 931e4b54947627df97a45131e712d10bc641138800d17b6c9fd57c1c137646816cb0709807289284aab9682b841bcb50db70ad58b2a4d31ac89dc27b0dfc4c1a
7
- data.tar.gz: 2211861bc3ce04d358aeeb530ec7382e06de454b662f424e64ead06f2bc38c64159fd2fc674bab40534eeb4f753eea52ce209481d4cd179b9d12193e13d168c2
6
+ metadata.gz: 316e6c5fda31c797fd8b17cecb1726ea252faed34982a193428529bff774c305850cf6cbc9446f30dafc74f658d43b0b955cece8d04fe08b2ce57049c82f0124
7
+ data.tar.gz: be58ff1da8a33e125b29d509ab33f454cfaa54d2d594c67b46a1470c81ae6171b77d3eb786f8d69f9cb5116555e8c17f28f8aea72f7b2d572ce65c0b22c143f6
data/README.md CHANGED
@@ -154,9 +154,9 @@ unencrypted key.
154
154
  Installation
155
155
  ------------
156
156
 
157
- If you're one of the chaps using Ruby 1.9.*, life is easy:
157
+ If you're one of the chaps using Ruby 1.9 or higher, life is easy:
158
158
 
159
- gem install ruby-manta-1.0.1.gem
159
+ gem install ruby-manta
160
160
 
161
161
  Done.
162
162
 
@@ -696,11 +696,11 @@ make a request to Manta at the given path. This is typically used to GET
696
696
  an object.
697
697
 
698
698
  expires is a Time object or integer representing time after epoch; this
699
- determines how long the signed URL will be valid for. The method is the HTTP
700
- method (:get, :put, :post, :delete) the signed URL is allowed to be used
701
- for. The path must be a valid object (or directory?) path. Lastly, the
702
- optional args is an array containing pairs of query args that will be
703
- appended at the end of the URL.
699
+ determines how long the signed URL will be valid for. The method is either a
700
+ single HTTP method (:get, :put, :post, :delete, :options) or a list of such
701
+ methods that the signed URL is allowed to be used for. The path must start
702
+ with /<user>/stor. Lastly, the optional args is an array containing pairs of
703
+ query args that will be appended at the end of the URL.
704
704
 
705
705
  The returned URL is signed, and can be used either over HTTP or HTTPS until
706
706
  it reaches the expiry date.
@@ -24,6 +24,7 @@ require 'digest'
24
24
  require 'time'
25
25
  require 'json'
26
26
  require 'cgi'
27
+ require 'uri'
27
28
 
28
29
  require File.expand_path('../version', __FILE__)
29
30
 
@@ -37,8 +38,8 @@ class MantaClient
37
38
  MAX_LIMIT = 1000
38
39
  HTTP_AGENT = "ruby-manta/#{LIB_VERSION} (#{RUBY_PLATFORM}; #{OpenSSL::OPENSSL_VERSION}) ruby/#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
39
40
  HTTP_SIGNATURE = 'Signature keyId="/%s/keys/%s",algorithm="%s",signature="%s"'
40
- OBJ_PATH_REGEX = Regexp.new('^/.+/(?:stor|public|reports)(?:/|$)')
41
- JOB_PATH_REGEX = Regexp.new('^/.+?/jobs/.+?(?:/live|$)')
41
+ OBJ_PATH_REGEX = Regexp.new('^/[^/]+(?:/?$|/stor|/public|/reports|/jobs)(?:/|$)')
42
+ JOB_PATH_REGEX = Regexp.new('^/[^/]+/jobs(?:/|$)')
42
43
 
43
44
  # match one or more protocol and hostnames, with optional port numbers.
44
45
  # E.g. "http://example.com https://example.com:8443"
@@ -99,7 +100,7 @@ class MantaClient
99
100
  @digest_name = 'dsa-sha1'
100
101
  algorithm = OpenSSL::PKey::DSA
101
102
  else
102
- raise UnsupportedKeyError
103
+ raise UnsupportedKey
103
104
  end
104
105
 
105
106
  @priv_key = algorithm.new(priv_key_data)
@@ -296,10 +297,8 @@ class MantaClient
296
297
  return true, result.headers if method == :head
297
298
 
298
299
  json_chunks = result.body.split("\n")
299
- sent_num_entries = result.headers['Result-Set-Size'].to_i
300
300
 
301
- if (json_chunks.size != sent_num_entries && json_chunks.size != limit) ||
302
- json_chunks.size > limit
301
+ if json_chunks.size > limit
303
302
  raise CorruptResult
304
303
  end
305
304
 
@@ -649,19 +648,20 @@ class MantaClient
649
648
 
650
649
  # Generates a signed URL which can be used by unauthenticated users to
651
650
  # make a request to Manta at the given path. This is typically used to GET
652
- # an object.
651
+ # an object, or to make a CORS preflighted PUT request.
653
652
  #
654
653
  # expires is a Time object or integer representing time after epoch; this
655
- # determines how long the signed URL will be valid for. The method is the HTTP
656
- # method (:get, :put, :post, :delete) the signed URL is allowed to be used
657
- # for. The path must start with /<user>/stor. Lastly, the optional args is an
658
- # array containing pairs of query args that will be appended at the end of
659
- # the URL.
654
+ # determines how long the signed URL will be valid for. The method is either a
655
+ # single HTTP method (:get, :put, :post, :delete, :options) or a list of such
656
+ # methods that the signed URL is allowed to be used for. The path must start
657
+ # with /<user>/stor. Lastly, the optional args is an array containing pairs of
658
+ # query args that will be appended at the end of the URL.
660
659
  #
661
660
  # The returned URL is signed, and can be used either over HTTP or HTTPS until
662
661
  # it reaches the expiry date.
663
662
  def gen_signed_url(expires, method, path, args=[])
664
- raise ArgumentError unless [:get, :put, :post, :delete].include? method
663
+ methods = method.is_a?(Array) ? method : [method]
664
+ raise ArgumentError unless (methods - [:get, :put, :post, :delete, :options]).empty?
665
665
  raise ArgumentError unless path =~ OBJ_PATH_REGEX
666
666
 
667
667
  key_id = '/%s/keys/%s' % [@user, @fingerprint]
@@ -670,14 +670,17 @@ class MantaClient
670
670
  args.push([ 'algorithm', @digest_name ])
671
671
  args.push([ 'keyId', key_id ])
672
672
 
673
+ method = methods.map {|m| m.to_s.upcase }.sort.join(",")
674
+ host = URI.encode(@host.split('/').last)
675
+ path = URI.encode(path)
676
+
677
+ args.push(['method', method]) if methods.count > 1
678
+
673
679
  encoded_args = args.sort.map do |key, val|
674
680
  # to comply with RFC 3986
675
681
  CGI.escape(key.to_s) + '=' + CGI.escape(val.to_s)
676
682
  end.join('&')
677
683
 
678
- method = method.to_s.upcase
679
- host = @host.split('/').last
680
-
681
684
  plaintext = "#{method}\n#{host}\n#{path}\n#{encoded_args}"
682
685
  signature = @priv_key.sign(@digest, plaintext)
683
686
  encoded_signature = CGI.escape(Base64.strict_encode64(signature))
@@ -739,7 +742,7 @@ class MantaClient
739
742
  def obj_url(path)
740
743
  raise ArgumentError unless path =~ OBJ_PATH_REGEX
741
744
 
742
- @host + path
745
+ URI.encode(@host + path)
743
746
  end
744
747
 
745
748
 
@@ -753,7 +756,7 @@ class MantaClient
753
756
  args.join('/')
754
757
  end
755
758
 
756
- @host + path
759
+ URI.encode(@host + path)
757
760
  end
758
761
 
759
762
 
@@ -1,3 +1,3 @@
1
1
  class MantaClient
2
- LIB_VERSION = '1.1.0'
2
+ LIB_VERSION = '1.2.0'
3
3
  end
@@ -3,7 +3,7 @@ require File.expand_path('../lib/version', __FILE__)
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'ruby-manta'
5
5
  s.version = MantaClient::LIB_VERSION
6
- s.date = '2013-06-24'
6
+ s.date = '2013-10-24'
7
7
  s.summary = "Interface for Joyent's Manta service."
8
8
  s.description = "A simple low-abstraction layer which communicates with Joyent's Manta service."
9
9
  s.authors = ['Joyent']
@@ -178,6 +178,15 @@ class TestMantaClient < MiniTest::Unit::TestCase
178
178
 
179
179
 
180
180
 
181
+ def test_root_directory
182
+ result, headers = @@client.list_directory('/' + @@user)
183
+ assert headers.is_a? Hash
184
+ assert_equal result.size, 4
185
+ assert_equal result.map { |r| r['name'] }.sort, ['jobs', 'public', 'reports', 'stor']
186
+ end
187
+
188
+
189
+
181
190
  def test_objects
182
191
  result, headers = @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
183
192
  assert_equal result, true
@@ -292,12 +301,25 @@ class TestMantaClient < MiniTest::Unit::TestCase
292
301
 
293
302
 
294
303
  def test_signed_urls
295
- @@client.put_object(@@test_dir_path + '/obj1', 'foo-data')
304
+
305
+ client = HTTPClient.new
306
+
307
+ put_url = @@client.gen_signed_url(Time.now + 500000, [:put, :options],
308
+ @@test_dir_path + '/obj1')
309
+
310
+ result = client.options("https://" + put_url, {
311
+ 'Access-Control-Request-Headers' => 'access-control-allow-origin, accept, content-type',
312
+ 'Access-Control-Request-Method' => 'PUT'
313
+ })
314
+
315
+ assert_equal result.status, 200
316
+
317
+ result = client.put("https://" + put_url, 'foo-data', { 'Content-Type' => 'text/plain' })
318
+ assert_equal result.status, 204
296
319
 
297
320
  url = @@client.gen_signed_url(Time.now + 500000, :get,
298
321
  @@test_dir_path + '/obj1')
299
322
 
300
- client = HTTPClient.new
301
323
  result = client.get('http://' + url)
302
324
  assert_equal result.body, 'foo-data'
303
325
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-manta
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joyent
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-24 00:00:00.000000000 Z
11
+ date: 2013-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.6.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: httpclient
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: 2.3.0.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.3.0.1
41
41
  description: A simple low-abstraction layer which communicates with Joyent's Manta
@@ -62,12 +62,12 @@ require_paths:
62
62
  - lib
63
63
  required_ruby_version: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ! '>='
65
+ - - '>='
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  requirements:
70
- - - ! '>='
70
+ - - '>='
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  requirements: []