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.
- data/lib/aws/core.rb +1 -1
- data/lib/aws/core/http/net_http_handler.rb +21 -62
- data/lib/aws/record/attribute_macros.rb +28 -4
- data/lib/aws/record/attributes/date.rb +89 -0
- data/lib/aws/record/base.rb +41 -4
- data/lib/aws/record/finder_methods.rb +7 -5
- data/lib/aws/record/scope.rb +32 -5
- data/lib/aws/s3/bucket.rb +14 -5
- data/lib/aws/s3/bucket_version_collection.rb +7 -11
- data/lib/aws/s3/client.rb +37 -1
- data/lib/aws/s3/client/xml.rb +8 -1
- data/lib/aws/s3/errors.rb +14 -0
- data/lib/aws/s3/multipart_upload_collection.rb +0 -3
- data/lib/aws/s3/object_collection.rb +182 -6
- data/lib/aws/s3/paginated_collection.rb +21 -40
- data/lib/aws/s3/prefix_and_delimiter_collection.rb +0 -7
- data/lib/aws/s3/presigned_post.rb +26 -11
- data/lib/aws/s3/request.rb +1 -1
- data/lib/aws/s3/s3_object.rb +10 -4
- data/lib/aws/s3/uploaded_part_collection.rb +3 -1
- data/lib/net/http/connection_pool.rb +193 -0
- data/lib/net/http/connection_pool/connection.rb +132 -0
- data/lib/net/http/connection_pool/session.rb +93 -0
- metadata +8 -4
data/lib/aws/core.rb
CHANGED
@@ -11,9 +11,7 @@
|
|
11
11
|
# ANY KIND, either express or implied. See the License for the specific
|
12
12
|
# language governing permissions and limitations under the License.
|
13
13
|
|
14
|
-
require 'net/http'
|
15
|
-
require 'net/https'
|
16
|
-
require 'openssl'
|
14
|
+
require 'net/http/connection_pool'
|
17
15
|
|
18
16
|
module AWS
|
19
17
|
module Core
|
@@ -22,72 +20,33 @@ module AWS
|
|
22
20
|
# The default http request handler for the aws-sdk gem. It is based
|
23
21
|
# on Net::Http.
|
24
22
|
class NetHttpHandler
|
25
|
-
|
26
|
-
def handle request, response
|
27
|
-
http_session_for(request) do |http|
|
28
|
-
begin
|
29
|
-
http_resp = http.request(build_request(request))
|
30
|
-
response.body = http_resp.body
|
31
|
-
response.status = http_resp.code.to_i
|
32
|
-
response.headers = http_resp.to_hash
|
33
|
-
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
34
|
-
response.timeout = true
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# @private
|
40
|
-
protected
|
41
|
-
def http_session_for request, &block
|
42
|
-
begin
|
43
|
-
http = build_http(request)
|
44
|
-
http.start
|
45
|
-
yield(http)
|
46
|
-
ensure
|
47
|
-
http.finish if http.started?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# @private
|
52
|
-
protected
|
53
|
-
def build_http request
|
54
|
-
|
55
|
-
http_args = []
|
56
|
-
http_args << request.host
|
57
|
-
http_args << (request.use_ssl? ? 443 : 80)
|
58
23
|
|
59
|
-
|
24
|
+
@@pool = Net::HTTP::ConnectionPool.new
|
60
25
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
http_args << proxy.password
|
68
|
-
end
|
26
|
+
# @private
|
27
|
+
def self.pool
|
28
|
+
@@pool
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle request, response
|
69
32
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
33
|
+
options = {}
|
34
|
+
options[:ssl] = request.use_ssl?
|
35
|
+
options[:proxy_uri] = request.proxy_uri
|
36
|
+
options[:ssl_verify_peer] = request.ssl_verify_peer?
|
37
|
+
options[:ssl_ca_file] = request.ssl_ca_file
|
74
38
|
|
75
|
-
|
39
|
+
connection = self.class.pool.connection_for(request.host, options)
|
76
40
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
else
|
86
|
-
http.use_ssl = false
|
41
|
+
begin
|
42
|
+
http_response = connection.request(build_request(request))
|
43
|
+
response.body = http_response.body
|
44
|
+
response.status = http_response.code.to_i
|
45
|
+
response.headers = http_response.to_hash
|
46
|
+
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
47
|
+
response.timeout = true
|
87
48
|
end
|
88
49
|
|
89
|
-
http
|
90
|
-
|
91
50
|
end
|
92
51
|
|
93
52
|
# @private
|
@@ -18,6 +18,7 @@ require 'aws/record/attributes/float'
|
|
18
18
|
require 'aws/record/attributes/sortable_float'
|
19
19
|
require 'aws/record/attributes/boolean'
|
20
20
|
require 'aws/record/attributes/datetime'
|
21
|
+
require 'aws/record/attributes/date'
|
21
22
|
|
22
23
|
module AWS
|
23
24
|
module Record
|
@@ -204,16 +205,39 @@ module AWS
|
|
204
205
|
# will be automanaged.
|
205
206
|
#
|
206
207
|
# @param [Symbol] name The name of the attribute.
|
208
|
+
#
|
207
209
|
# @param [Hash] options
|
208
|
-
#
|
209
|
-
# serialized with the correct number of digits to SimpleDB, left
|
210
|
-
# padded by zeros to allow sorting.
|
210
|
+
#
|
211
211
|
# @option options [Boolean] :set (false) When true this attribute
|
212
|
-
# can have multiple
|
212
|
+
# can have multiple date times.
|
213
|
+
#
|
213
214
|
def datetime_attr name, options = {}
|
214
215
|
add_attribute(DateTimeAttribute.new(name, options))
|
215
216
|
end
|
216
217
|
|
218
|
+
# Adds a date attribute to this class.
|
219
|
+
#
|
220
|
+
# @example A standard date attribute
|
221
|
+
#
|
222
|
+
# class Person < AWS::Record::Base
|
223
|
+
# date_attr :birthdate
|
224
|
+
# end
|
225
|
+
#
|
226
|
+
# baby = Person.new
|
227
|
+
# baby.birthdate = Time.now
|
228
|
+
# baby.birthdate #=> <Date: ....>
|
229
|
+
#
|
230
|
+
# @param [Symbol] name The name of the attribute.
|
231
|
+
#
|
232
|
+
# @param [Hash] options
|
233
|
+
#
|
234
|
+
# @option options [Boolean] :set (false) When true this attribute
|
235
|
+
# can have multiple dates.
|
236
|
+
#
|
237
|
+
def date_attr name, options = {}
|
238
|
+
add_attribute(DateAttribute.new(name, options))
|
239
|
+
end
|
240
|
+
|
217
241
|
# A convenience method for adding the standard two datetime attributes
|
218
242
|
# +:created_at+ and +:updated_at+.
|
219
243
|
#
|
@@ -0,0 +1,89 @@
|
|
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 'date'
|
15
|
+
require 'aws/record/attribute'
|
16
|
+
|
17
|
+
module AWS
|
18
|
+
module Record
|
19
|
+
|
20
|
+
# @private
|
21
|
+
class DateAttribute < Attribute
|
22
|
+
|
23
|
+
# Returns value cast to a Date object. Empty strings are cast to
|
24
|
+
# nil. Values are cast first to strings and then passed to
|
25
|
+
# Date.parse. Integers are treated as timestamps.
|
26
|
+
#
|
27
|
+
# date_attribute.type_cast('2000-01-02T10:11:12Z')
|
28
|
+
# #=> #<Date: 4903091/2,0,2299161>
|
29
|
+
#
|
30
|
+
# date_attribute.type_cast(1306170146)
|
31
|
+
# #<Date: 4911409/2,0,2299161>
|
32
|
+
#
|
33
|
+
# date_attribute.type_cast('')
|
34
|
+
# #=> nil
|
35
|
+
#
|
36
|
+
# date_attribute.type_cast(nil)
|
37
|
+
# #=> nil
|
38
|
+
#
|
39
|
+
# @param [Mixed] raw_value The value to cast to a Date object.
|
40
|
+
# @param [Hash] options
|
41
|
+
# @return [Date,nil]
|
42
|
+
def self.type_cast raw_value, options = {}
|
43
|
+
case raw_value
|
44
|
+
when nil then nil
|
45
|
+
when '' then nil
|
46
|
+
when Date then raw_value
|
47
|
+
when Integer then
|
48
|
+
begin
|
49
|
+
Date.parse(Time.at(raw_value).to_s) # assumed timestamp
|
50
|
+
rescue
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
else
|
54
|
+
begin
|
55
|
+
Date.parse(raw_value.to_s) # Time, DateTime or String
|
56
|
+
rescue
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns a Date object encoded as a string (suitable for sorting).
|
63
|
+
#
|
64
|
+
# attribute.serialize(DateTime.parse('2001-01-01'))
|
65
|
+
# #=> '2001-01-01'
|
66
|
+
#
|
67
|
+
# @param [Date] datetime The date to serialize.
|
68
|
+
#
|
69
|
+
# @param [Hash] options
|
70
|
+
#
|
71
|
+
# @return [String] Returns the date object serialized to a string
|
72
|
+
# ('YYYY-MM-DD').
|
73
|
+
#
|
74
|
+
def self.serialize date, options = {}
|
75
|
+
unless date.is_a?(Date)
|
76
|
+
raise ArgumentError, "expected a Date value, got #{date.class}"
|
77
|
+
end
|
78
|
+
date.strftime('%Y-%m-%d')
|
79
|
+
end
|
80
|
+
|
81
|
+
# @private
|
82
|
+
def self.allow_set?
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/lib/aws/record/base.rb
CHANGED
@@ -301,11 +301,23 @@ module AWS
|
|
301
301
|
#
|
302
302
|
# @param [Hash] attributes A set of attribute values to seed this record
|
303
303
|
# with. The attributes are bulk assigned.
|
304
|
+
#
|
304
305
|
# @return [Base] Returns a new record that has not been persisted yet.
|
306
|
+
#
|
305
307
|
def initialize attributes = {}
|
308
|
+
|
309
|
+
opts = attributes.dup
|
310
|
+
|
306
311
|
@_data = {}
|
312
|
+
|
313
|
+
@_domain = attributes.delete(:domain)
|
314
|
+
@_domain ||= attributes.delete('domain')
|
315
|
+
@_domain = self.class.domain_name(@_domain)
|
316
|
+
|
307
317
|
assign_default_values
|
318
|
+
|
308
319
|
bulk_assign(attributes)
|
320
|
+
|
309
321
|
end
|
310
322
|
|
311
323
|
# The id for each record is auto-generated. The default strategy
|
@@ -316,6 +328,12 @@ module AWS
|
|
316
328
|
@_id
|
317
329
|
end
|
318
330
|
|
331
|
+
# @return [String] Returns the name of the SimpleDB domain this record
|
332
|
+
# is persisted to or will be persisted to.
|
333
|
+
def domain
|
334
|
+
@_domain
|
335
|
+
end
|
336
|
+
|
319
337
|
# @return [Hash] A hash with attribute names as hash keys (strings) and
|
320
338
|
# attribute values (of mixed types) as hash values.
|
321
339
|
def attributes
|
@@ -450,7 +468,13 @@ module AWS
|
|
450
468
|
# @param [String] name Defaults to the name of this class.
|
451
469
|
# @return [String] Returns the full prefixed domain name for this class.
|
452
470
|
def domain_name name = nil
|
453
|
-
|
471
|
+
|
472
|
+
name = @_domain_name if name.nil?
|
473
|
+
name = self.name if name.nil?
|
474
|
+
name = name.name if name.is_a?(SimpleDB::Domain)
|
475
|
+
|
476
|
+
"#{Record.domain_prefix}#{name}"
|
477
|
+
|
454
478
|
end
|
455
479
|
|
456
480
|
# Creates the SimpleDB domain that is configured for this class.
|
@@ -461,14 +485,19 @@ module AWS
|
|
461
485
|
# @return [AWS::SimpleDB::Domain]
|
462
486
|
#
|
463
487
|
def create_domain name = nil
|
464
|
-
|
488
|
+
sdb.domains.create(domain_name(name))
|
465
489
|
end
|
466
490
|
|
467
491
|
# @return [AWS::SimpleDB::Domain] Returns a reference to the domain
|
468
492
|
# this class will save data to.
|
469
493
|
# @private
|
470
494
|
def sdb_domain name = nil
|
471
|
-
|
495
|
+
sdb.domains[domain_name(name)]
|
496
|
+
end
|
497
|
+
|
498
|
+
protected
|
499
|
+
def sdb
|
500
|
+
AWS::SimpleDB.new
|
472
501
|
end
|
473
502
|
|
474
503
|
end
|
@@ -547,7 +576,14 @@ module AWS
|
|
547
576
|
# @private
|
548
577
|
private
|
549
578
|
def sdb_item
|
550
|
-
|
579
|
+
sdb_domain.items[id]
|
580
|
+
end
|
581
|
+
|
582
|
+
# @return [SimpleDB::Domain] Returns the domain this record is
|
583
|
+
# persisted to or will be persisted to.
|
584
|
+
private
|
585
|
+
def sdb_domain
|
586
|
+
self.class.sdb_domain(domain)
|
551
587
|
end
|
552
588
|
|
553
589
|
# @private
|
@@ -589,6 +625,7 @@ module AWS
|
|
589
625
|
# @todo need to do something about partial hyrdation of attributes
|
590
626
|
private
|
591
627
|
def hydrate id, data
|
628
|
+
|
592
629
|
@_id = id
|
593
630
|
|
594
631
|
# New objects are populated with default values, but we don't
|
@@ -29,11 +29,13 @@ module AWS
|
|
29
29
|
# Record::Base
|
30
30
|
def find_by_id id, options = {}
|
31
31
|
|
32
|
-
|
32
|
+
domain = sdb_domain(options[:domain])
|
33
|
+
|
34
|
+
data = domain.items[id].data.attributes
|
33
35
|
|
34
36
|
raise RecordNotFound, "no data found for id: #{id}" if data.empty?
|
35
37
|
|
36
|
-
obj = self.new
|
38
|
+
obj = self.new(:domain => domain)
|
37
39
|
obj.send(:hydrate, id, data)
|
38
40
|
obj
|
39
41
|
|
@@ -117,7 +119,7 @@ module AWS
|
|
117
119
|
#
|
118
120
|
# @return [Scope] Returns an enumerable scope object.
|
119
121
|
def all options = {}
|
120
|
-
find(:all, options)
|
122
|
+
_new_scope.find(:all, options)
|
121
123
|
end
|
122
124
|
|
123
125
|
# Counts records in SimpleDB.
|
@@ -143,7 +145,7 @@ module AWS
|
|
143
145
|
# records are counted.
|
144
146
|
# @option options [Integer] :limit The max number of records to count.
|
145
147
|
def count(options = {})
|
146
|
-
|
148
|
+
_new_scope.count(options)
|
147
149
|
end
|
148
150
|
alias_method :size, :count
|
149
151
|
|
@@ -151,7 +153,7 @@ module AWS
|
|
151
153
|
# class. If there are no records in the current classes domain, then
|
152
154
|
# nil is returned.
|
153
155
|
def first options = {}
|
154
|
-
_new_scope.
|
156
|
+
_new_scope.first(options)
|
155
157
|
end
|
156
158
|
|
157
159
|
# Limits which records are retried from SimpleDB when performing a find.
|
data/lib/aws/record/scope.rb
CHANGED
@@ -58,13 +58,34 @@ module AWS
|
|
58
58
|
# @private
|
59
59
|
def initialize base_class, options = {}
|
60
60
|
@base_class = base_class
|
61
|
-
@options = options
|
61
|
+
@options = options.dup
|
62
|
+
@options[:where] ||= []
|
63
|
+
@options[:domain] ||= base_class.domain_name
|
62
64
|
end
|
63
65
|
|
64
66
|
# @return [Class] Returns the AWS::Record::Base extending class that
|
65
67
|
# this scope will find records for.
|
66
68
|
attr_reader :base_class
|
67
69
|
|
70
|
+
def new attributes = {}
|
71
|
+
|
72
|
+
options = {}
|
73
|
+
options.merge!(attributes)
|
74
|
+
unless options.key?(:domain) or options.key?('domain')
|
75
|
+
options[:domain] = _domain
|
76
|
+
end
|
77
|
+
|
78
|
+
@options[:where].each do |conditions|
|
79
|
+
if conditions.size == 1 and conditions.first.is_a?(Hash)
|
80
|
+
options.merge!(conditions.first)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
base_class.new(options)
|
85
|
+
|
86
|
+
end
|
87
|
+
alias_method :build, :new
|
88
|
+
|
68
89
|
# @param [String] domain
|
69
90
|
# @return [Scope] Returns a scope for restricting the domain of subsequent
|
70
91
|
# scope operations
|
@@ -102,7 +123,7 @@ module AWS
|
|
102
123
|
|
103
124
|
case
|
104
125
|
when id_or_mode == :all then scope
|
105
|
-
when id_or_mode == :first then scope.limit(1).first
|
126
|
+
when id_or_mode == :first then scope.limit(1).to_a.first
|
106
127
|
else
|
107
128
|
base_class.find_by_id(id_or_mode, :domain => scope._domain)
|
108
129
|
end
|
@@ -120,6 +141,12 @@ module AWS
|
|
120
141
|
end
|
121
142
|
alias_method :size, :count
|
122
143
|
|
144
|
+
# @return [Record::Base,nil] Gets the first record from the domain
|
145
|
+
# and returns it, or returns nil if the domain is empty.
|
146
|
+
def first options = {}
|
147
|
+
_handle_options(options).find(:first)
|
148
|
+
end
|
149
|
+
|
123
150
|
# Applies conditions to the scope that limit which records are returned.
|
124
151
|
# Only those matching all given conditions will be returned.
|
125
152
|
#
|
@@ -149,7 +176,7 @@ module AWS
|
|
149
176
|
if conditions.empty?
|
150
177
|
raise ArgumentError, 'missing required condition'
|
151
178
|
end
|
152
|
-
_with(:where =>
|
179
|
+
_with(:where => @options[:where] + [conditions])
|
153
180
|
end
|
154
181
|
|
155
182
|
# Specifies how to sort records returned.
|
@@ -213,7 +240,7 @@ module AWS
|
|
213
240
|
items = _item_collection
|
214
241
|
|
215
242
|
items.select.each do |item_data|
|
216
|
-
obj = base_class.new
|
243
|
+
obj = base_class.new(:domain => _domain)
|
217
244
|
obj.send(:hydrate, item_data.name, item_data.attributes)
|
218
245
|
yield(obj)
|
219
246
|
end
|
@@ -287,7 +314,7 @@ module AWS
|
|
287
314
|
items = base_class.sdb_domain(_domain).items
|
288
315
|
items = items.order(*@options[:order]) if @options[:order]
|
289
316
|
items = items.limit(*@options[:limit]) if @options[:limit]
|
290
|
-
|
317
|
+
@options[:where].each do |where_condition|
|
291
318
|
items = items.where(*where_condition)
|
292
319
|
end
|
293
320
|
items
|