aws-sdk 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,13 +19,6 @@ module AWS
19
19
 
20
20
  include PrefixedCollection
21
21
 
22
- def each(options = {}, &block)
23
- each_page(options) do |page|
24
- each_member_in_page(page, &block)
25
- end
26
- nil
27
- end
28
-
29
22
  # @see Bucket#as_tree
30
23
  def as_tree options = {}
31
24
  Tree.new(self, { :prefix => prefix }.merge(options))
@@ -340,15 +340,21 @@ module AWS
340
340
  # long as they are described by a policy condition (see
341
341
  # {#where}).
342
342
  def fields
343
- signature =
344
- config.signer.sign(policy, "sha1")
345
343
 
346
- {
344
+ signature = config.signer.sign(policy, "sha1")
345
+
346
+ fields = {
347
347
  "AWSAccessKeyId" => config.signer.access_key_id,
348
348
  "key" => key,
349
349
  "policy" => policy,
350
350
  "signature" => signature
351
351
  }.merge(optional_fields)
352
+
353
+ fields["x-amz-security-token"] = config.signer.session_token if
354
+ config.signer.session_token
355
+
356
+ fields.merge(optional_fields)
357
+
352
358
  end
353
359
 
354
360
  # @private
@@ -482,14 +488,23 @@ module AWS
482
488
  # @private
483
489
  private
484
490
  def generate_conditions
485
- conditions.inject([]) do |ary, (field, field_conds)|
486
- ary += field_conds
487
- end +
488
- [{ "bucket" => bucket.name }] +
489
- key_conditions +
490
- optional_fields.map { |(n, v)| Hash[[[n, v]]] } +
491
- range_conditions +
492
- ignored_conditions
491
+
492
+ conditions = self.conditions.inject([]) do |list, (field, field_conds)|
493
+ list + field_conds
494
+ end
495
+
496
+ conditions << { "bucket" => bucket.name }
497
+ conditions += key_conditions
498
+ conditions += optional_fields.map { |(n, v)| Hash[[[n, v]]] }
499
+ conditions += range_conditions
500
+ conditions += ignored_conditions
501
+
502
+ if config.signer.session_token
503
+ conditions << {"x-amz-security-token" => config.signer.session_token}
504
+ end
505
+
506
+ conditions
507
+
493
508
  end
494
509
 
495
510
  # @private
@@ -184,7 +184,7 @@ module AWS
184
184
  def sub_resources
185
185
  %w(acl location logging notification partNumber policy
186
186
  requestPayment torrent uploadId uploads versionId
187
- versioning versions)
187
+ versioning versions delete)
188
188
  end
189
189
 
190
190
  def query_parameters
@@ -410,13 +410,12 @@ module AWS
410
410
  upload = multipart_uploads.create(options)
411
411
 
412
412
  if block_given?
413
- result = nil
414
413
  begin
415
414
  yield(upload)
416
- ensure
417
- result = upload.close
415
+ upload.close
416
+ rescue
417
+ upload.abort
418
418
  end
419
- result
420
419
  else
421
420
  upload
422
421
  end
@@ -488,6 +487,10 @@ module AWS
488
487
  # option in the current configuration; for more information,
489
488
  # see {AWS.config}.
490
489
  #
490
+ # @option options :cache_control [String] Can be used to specify
491
+ # caching behavior. See
492
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
493
+ #
491
494
  # @return [nil]
492
495
  def copy_from source, options = {}
493
496
 
@@ -524,6 +527,8 @@ module AWS
524
527
  copy_opts[:server_side_encryption] =
525
528
  options[:server_side_encryption] if
526
529
  options.key?(:server_side_encryption)
530
+ copy_opts[:cache_control] = options[:cache_control] if
531
+ options[:cache_control]
527
532
  add_configured_write_options(copy_opts)
528
533
 
529
534
  if options[:reduced_redundancy]
@@ -641,6 +646,7 @@ module AWS
641
646
  # the object ETag matches the provided value.
642
647
  #
643
648
  # @option options [Range] :range A byte range to read data from
649
+ #
644
650
  def read(options = {}, &blk)
645
651
  options[:bucket_name] = bucket.name
646
652
  options[:key] = key
@@ -74,7 +74,9 @@ module AWS
74
74
 
75
75
  # @private
76
76
  protected
77
- def pagination_markers; [:part_number_marker]; end
77
+ def pagination_markers
78
+ [:part_number_marker]
79
+ end
78
80
 
79
81
  end
80
82
 
@@ -0,0 +1,193 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'net/http/connection_pool/session'
15
+ require 'net/http/connection_pool/connection'
16
+ require 'thread'
17
+
18
+ # @private
19
+ class Net::HTTP::ConnectionPool
20
+
21
+ SOCKET_ERRORS = [
22
+ EOFError,
23
+ IOError,
24
+ Errno::ECONNABORTED,
25
+ Errno::ECONNRESET,
26
+ Errno::EPIPE,
27
+ Errno::EINVAL
28
+ ]
29
+
30
+ # @params [Hash] options
31
+ #
32
+ # @option options [Numeric] :idle_timeout (60) The number of seconds a
33
+ # connection is allowed to sit idle before it is closed and removed
34
+ # from the pool.
35
+ #
36
+ # @option options [Numeric] :open_timeout (15) The number of seconds to
37
+ # wait when opening a http session before raising a timeout exception.
38
+ #
39
+ def initialize options = {}
40
+ @pool = []
41
+ @pool_mutex = Mutex.new
42
+ @open_timeout = options[:open_timeout] || 15
43
+ @idle_timeout = options[:idle_timeout] || 60
44
+ end
45
+
46
+ # @return [Integer]
47
+ attr_reader :idle_timeout
48
+
49
+ # @return [Integer]
50
+ attr_accessor :open_timeout
51
+
52
+ # Requests a http session from the connection pool.
53
+ #
54
+ # pool.connection_for('domain.com') do |connection|
55
+ #
56
+ # # make
57
+ # connection.request(Net::HTTP::Get.new('/index.html'))
58
+ # connection.request(Net::HTTP::Get.new('/about.html'))
59
+ #
60
+ # end
61
+ #
62
+ # The yielded connection object is a thin wrapper around the persistent
63
+ # http session object. You generally want to call {Connection#request}
64
+ # on the yielded object. When the block is complete the connection
65
+ # will be returned to the pool.
66
+ #
67
+ # @param [String] host
68
+ #
69
+ # @param [Hash] options
70
+ #
71
+ # @option options [Integer] :port Which port the connection should use.
72
+ # Defaults to 80, unless +:ssl+ is +true+, then it defaults to 443.
73
+ #
74
+ # @option options [Boolean] :ssl If the connection should be made over
75
+ # SSL. Defaults to +false+, unless +:port+ is 443, then it defaults
76
+ # to +true+.
77
+ #
78
+ # @option options [Boolean] :ssl_verify_peer (true) If true, ssl
79
+ # connections will verify peer certificates. This should only ever be
80
+ # set false false for debugging purposes.
81
+ #
82
+ # @option options [String] :ssl_ca_file Full path to the SSL certificate
83
+ # authority bundle file that should be used when verifying peer
84
+ # certificates. If you do not pass +:ssl_ca_file+ or +:ssl_ca_path+
85
+ # the the system default will be used if available.
86
+ #
87
+ # @option options [String] :ssl_ca_path Full path of the directory that
88
+ # contains the unbundled SSL certificate authority files for verifying
89
+ # peer certificates. If you do not pass +:ssl_ca_file+ or +:ssl_ca_path+
90
+ # the the system default will be used if available.
91
+ #
92
+ # @option options [URI::HTTP,String] :proxy_uri (nil) A URI string or
93
+ # URI::HTTP for a proxy reqeusts should be made through. You should
94
+ # not pass both +:proxy_uri+ with any of the other proxy options.
95
+ #
96
+ # :proxy_uri => 'http://user:pass@host.com:80'
97
+ #
98
+ # @option options [String] :proxy_address
99
+ #
100
+ # @option options [String] :proxy_port
101
+ #
102
+ # @option options [String] :proxy_user
103
+ #
104
+ # @option options [String] :proxy_password
105
+ #
106
+ # @yieldparam [Connection] connection
107
+ #
108
+ # @return [nil]
109
+ #
110
+ def connection_for host, options = {}, &block
111
+ connection = Connection.new(self, host, options)
112
+ if block_given?
113
+ yield(connection)
114
+ else
115
+ connection
116
+ end
117
+ end
118
+
119
+ def request connection, *request_args, &block
120
+ session = nil
121
+ response = nil
122
+ retried = false
123
+ begin
124
+ session = session_for(connection)
125
+ session.http_session.read_timeout = connection.read_timeout
126
+ response = session.request(*request_args, &block)
127
+ rescue *SOCKET_ERRORS => error
128
+ # retry socket errors once
129
+ unless retried
130
+ retried = true
131
+ retry
132
+ end
133
+ raise error
134
+ else
135
+ @pool_mutex.synchronize { @pool << session }
136
+ end
137
+ response
138
+ end
139
+
140
+ # Returns the number of sessions currently in the pool, not counting those
141
+ # currently in use.
142
+ def size
143
+ @pool_mutex.synchronize { @pool.size }
144
+ end
145
+
146
+ # Removes http sessions from the pool that have passed the idle timeout
147
+ def clean!
148
+ @pool_mutex.synchronize { _clean }
149
+ end
150
+
151
+ # Finishes and removes removes all sessions from the pool.
152
+ # If empty! is called while there are outstanding requests they may
153
+ # get checked back into the pool, leaving the pool in a non-empty state.
154
+ def empty!
155
+ @pool_mutex.synchronize do
156
+ @pool.each(&:finish)
157
+ @pool = []
158
+ end
159
+ end
160
+
161
+ # Returns a suitable session from the pool or creates a new one
162
+ private
163
+ def session_for connection
164
+ session = nil
165
+
166
+ @pool_mutex.synchronize do
167
+ _clean
168
+ session = @pool.find{|idle_session| idle_session.key == connection.key }
169
+ @pool.delete(session) if session
170
+ end
171
+
172
+ if session.nil?
173
+ session = Session.for(connection, open_timeout)
174
+ end
175
+
176
+ session
177
+ end
178
+
179
+ private
180
+ def _clean
181
+ now = Time.now
182
+ @pool.delete_if do |idle_session|
183
+ if
184
+ idle_session.last_used_at.nil? or
185
+ now - idle_session.last_used_at > idle_timeout
186
+ then
187
+ idle_session.finish
188
+ true
189
+ end
190
+ end
191
+ end
192
+
193
+ end
@@ -0,0 +1,132 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'uri'
15
+
16
+ class Net::HTTP::ConnectionPool
17
+
18
+ # A light wrapper around Net::HTTP.
19
+ #
20
+ # You should not need to construct connection objects yourself.
21
+ # You receive them as a response to {ConnectionPool#connection_for}.
22
+ #
23
+ class Connection
24
+
25
+ # @param [ConnectionPool] pool
26
+ # @param (see ConnectionPool#connection_for)
27
+ # @option (see ConnectionPool#connection_for)
28
+ # @return [Connection]
29
+ def initialize pool, host, options = {}
30
+
31
+ @pool = pool
32
+
33
+ @host = host
34
+
35
+ @port = options.key?(:port) ? options[:port] : (options[:ssl] ? 443 : 80)
36
+
37
+ @ssl = options.key?(:ssl) ? options[:ssl] : (port == 443)
38
+
39
+ @ssl_verify_peer = options.key?(:ssl_verify_peer) ?
40
+ options[:ssl_verify_peer] : true
41
+
42
+ @ssl_ca_file = options[:ssl_ca_file]
43
+
44
+ @ssl_ca_path = options[:ssl_ca_path]
45
+
46
+ if uri = options[:proxy_uri]
47
+ uri = URI.parse(uri) if uri.is_a?(String)
48
+ @proxy_address = uri.host
49
+ @proxy_port = uri.port
50
+ @proxy_user = uri.user
51
+ @proxy_password = uri.password
52
+ else
53
+ @proxy_address = options[:proxy_address]
54
+ @proxy_port = options[:proxy_port]
55
+ @proxy_user = options[:proxy_user]
56
+ @proxy_password = options[:proxy_password]
57
+ end
58
+
59
+ @read_timeout = options[:read_timeout] || 60
60
+
61
+ end
62
+
63
+ # @return [ConnectionPool]
64
+ attr_reader :pool
65
+
66
+ # @return [String]
67
+ attr_reader :host
68
+
69
+ # @return [Integer]
70
+ attr_reader :port
71
+
72
+ # @return [Boolean]
73
+ attr_reader :ssl
74
+
75
+ # @return [Boolean]
76
+ attr_reader :ssl_verify_peer
77
+
78
+ # @return [String,nil]
79
+ attr_reader :ssl_ca_file
80
+
81
+ # @return [String,nil]
82
+ attr_reader :ssl_ca_path
83
+
84
+ # @return [String,nil]
85
+ attr_reader :proxy_address
86
+
87
+ # @return [Integer,nil]
88
+ attr_reader :proxy_port
89
+
90
+ # @return [String,nil]
91
+ attr_reader :proxy_user
92
+
93
+ # @return [String,nil]
94
+ attr_reader :proxy_password
95
+
96
+ # @return [Numeric,nil]
97
+ attr_accessor :read_timeout
98
+
99
+ # @return [Boolean] Returns true if this connection requires SSL.
100
+ def ssl?
101
+ @ssl
102
+ end
103
+
104
+ # @return [Boolean] Returns true if ssl connections should verify the
105
+ # peer certificate.
106
+ def ssl_verify_peer?
107
+ @ssl_verify_peer
108
+ end
109
+
110
+ # @return [Boolean] Returns true if this connection proxies requests.
111
+ def proxy?
112
+ !!proxy_address
113
+ end
114
+
115
+ def request *args, &block
116
+ pool.request(self, *args, &block)
117
+ end
118
+
119
+ # @return [String] Returns a key that can be used to group connections
120
+ # that connection to the same host.
121
+ def key
122
+ @key ||= begin
123
+ %w(
124
+ host port
125
+ ssl ssl_verify_peer ssl_ca_file ssl_ca_path
126
+ proxy_address proxy_port proxy_user proxy_password
127
+ ).map{|part| send(part).to_s }.join(":")
128
+ end
129
+ end
130
+
131
+ end
132
+ end