aws 2.3.26 → 2.3.27
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/awsbase/right_awsbase.rb +146 -139
- data/lib/s3/right_s3_interface.rb +65 -62
- data/lib/sdb/right_sdb_interface.rb +20 -7
- metadata +5 -5
@@ -31,7 +31,7 @@ module Aws
|
|
31
31
|
require 'active_support/core_ext'
|
32
32
|
|
33
33
|
class AwsUtils #:nodoc:
|
34
|
-
@@digest1
|
34
|
+
@@digest1 = OpenSSL::Digest::Digest.new("sha1")
|
35
35
|
@@digest256 = nil
|
36
36
|
if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
|
37
37
|
@@digest256 = OpenSSL::Digest::Digest.new("sha256") rescue nil # Some installation may not support sha256
|
@@ -53,18 +53,18 @@ module Aws
|
|
53
53
|
# A deprecated guy (should work till septemper 2009)
|
54
54
|
def self.sign_request_v0(aws_secret_access_key, service_hash)
|
55
55
|
fix_service_params(service_hash, '0')
|
56
|
-
string_to_sign
|
56
|
+
string_to_sign = "#{service_hash['Action']}#{service_hash['Timestamp'] || service_hash['Expires']}"
|
57
57
|
service_hash['Signature'] = AwsUtils::sign(aws_secret_access_key, string_to_sign)
|
58
|
-
service_hash.to_a.collect{|key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
58
|
+
service_hash.to_a.collect { |key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
59
59
|
end
|
60
60
|
|
61
61
|
# Signature Version 1
|
62
62
|
# Another deprecated guy (should work till septemper 2009)
|
63
63
|
def self.sign_request_v1(aws_secret_access_key, service_hash)
|
64
64
|
fix_service_params(service_hash, '1')
|
65
|
-
string_to_sign
|
65
|
+
string_to_sign = service_hash.sort { |a, b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase) }.to_s
|
66
66
|
service_hash['Signature'] = AwsUtils::sign(aws_secret_access_key, string_to_sign)
|
67
|
-
service_hash.to_a.collect{|key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
67
|
+
service_hash.to_a.collect { |key, val| "#{amz_escape(key)}=#{amz_escape(val.to_s)}" }.join("&")
|
68
68
|
end
|
69
69
|
|
70
70
|
# Signature Version 2
|
@@ -78,20 +78,20 @@ module Aws
|
|
78
78
|
service_hash['SignatureMethod'] = 'HmacSHA256' unless ['HmacSHA256', 'HmacSHA1'].include?(service_hash['SignatureMethod'])
|
79
79
|
service_hash['SignatureMethod'] = 'HmacSHA1' unless @@digest256
|
80
80
|
# select a digest
|
81
|
-
digest
|
81
|
+
digest = (service_hash['SignatureMethod'] == 'HmacSHA256' ? @@digest256 : @@digest1)
|
82
82
|
# form string to sign
|
83
83
|
canonical_string = service_hash.keys.sort.map do |key|
|
84
84
|
"#{amz_escape(key)}=#{amz_escape(service_hash[key])}"
|
85
85
|
end.join('&')
|
86
|
-
string_to_sign
|
86
|
+
string_to_sign = "#{http_verb.to_s.upcase}\n#{host.downcase}\n#{uri}\n#{canonical_string}"
|
87
87
|
# sign the string
|
88
|
-
signature
|
89
|
-
ret
|
88
|
+
signature = escape_sig(Base64.encode64(OpenSSL::HMAC.digest(digest, aws_secret_access_key, string_to_sign)).strip)
|
89
|
+
ret = "#{canonical_string}&Signature=#{signature}"
|
90
90
|
# puts 'full=' + ret.inspect
|
91
91
|
ret
|
92
92
|
end
|
93
93
|
|
94
|
-
HEX
|
94
|
+
HEX = [
|
95
95
|
"%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
|
96
96
|
"%08", "%09", "%0A", "%0B", "%0C", "%0D", "%0E", "%0F",
|
97
97
|
"%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
|
@@ -126,7 +126,7 @@ module Aws
|
|
126
126
|
"%F8", "%F9", "%FA", "%FB", "%FC", "%FD", "%FE", "%FF"
|
127
127
|
]
|
128
128
|
TO_REMEMBER = 'AZaz09 -_.!~*\'()'
|
129
|
-
ASCII
|
129
|
+
ASCII = {} # {'A'=>65, 'Z'=>90, 'a'=>97, 'z'=>122, '0'=>48, '9'=>57, ' '=>32, '-'=>45, '_'=>95, '.'=>}
|
130
130
|
TO_REMEMBER.each_char do |c| #unpack("c*").each do |c|
|
131
131
|
ASCII[c] = c.unpack("c")[0]
|
132
132
|
end
|
@@ -139,7 +139,7 @@ module Aws
|
|
139
139
|
param = param.to_s
|
140
140
|
# param = param.force_encoding("UTF-8")
|
141
141
|
|
142
|
-
e
|
142
|
+
e = "x" # escape2(param.to_s)
|
143
143
|
# puts 'ESCAPED=' + e.inspect
|
144
144
|
|
145
145
|
|
@@ -154,10 +154,10 @@ module Aws
|
|
154
154
|
# e = converter.iconv(e) #.unpack('U*').select{ |cp| cp < 127 }.pack('U*')
|
155
155
|
# puts 'e out=' + e.inspect
|
156
156
|
|
157
|
-
e2
|
158
|
-
e2
|
159
|
-
e2
|
160
|
-
e2
|
157
|
+
e2 = CGI.escape(param)
|
158
|
+
e2 = e2.gsub("%7E", "~")
|
159
|
+
e2 = e2.gsub("+", "%20")
|
160
|
+
e2 = e2.gsub("*", "%2A")
|
161
161
|
|
162
162
|
# puts 'E2=' + e2.inspect
|
163
163
|
# puts e == e2.to_s
|
@@ -218,13 +218,13 @@ module Aws
|
|
218
218
|
|
219
219
|
def self.allow_only(allowed_keys, params)
|
220
220
|
bogus_args = []
|
221
|
-
params.keys.each {|p| bogus_args.push(p) unless allowed_keys.include?(p) }
|
221
|
+
params.keys.each { |p| bogus_args.push(p) unless allowed_keys.include?(p) }
|
222
222
|
raise AwsError.new("The following arguments were given but are not legal for the function call #{caller_method}: #{bogus_args.inspect}") if bogus_args.length > 0
|
223
223
|
end
|
224
224
|
|
225
225
|
def self.mandatory_arguments(required_args, params)
|
226
226
|
rargs = required_args.dup
|
227
|
-
params.keys.each {|p| rargs.delete(p)}
|
227
|
+
params.keys.each { |p| rargs.delete(p) }
|
228
228
|
raise AwsError.new("The following mandatory arguments were not provided to #{caller_method}: #{rargs.inspect}") if rargs.length > 0
|
229
229
|
end
|
230
230
|
|
@@ -242,7 +242,7 @@ module Aws
|
|
242
242
|
# Benchmark::Tms instance for service (Ec2, S3, or SQS) access benchmarking.
|
243
243
|
@service = Benchmark::Tms.new()
|
244
244
|
# Benchmark::Tms instance for XML parsing benchmarking.
|
245
|
-
@xml
|
245
|
+
@xml = Benchmark::Tms.new()
|
246
246
|
end
|
247
247
|
end
|
248
248
|
|
@@ -255,15 +255,15 @@ module Aws
|
|
255
255
|
|
256
256
|
# Text, if found in an error message returned by AWS, indicates that this may be a transient
|
257
257
|
# error. Transient errors are automatically retried with exponential back-off.
|
258
|
-
AMAZON_PROBLEMS
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
258
|
+
AMAZON_PROBLEMS = ['internal service error',
|
259
|
+
'is currently unavailable',
|
260
|
+
'no response from',
|
261
|
+
'Please try again',
|
262
|
+
'InternalError',
|
263
|
+
'ServiceUnavailable', #from SQS docs
|
264
|
+
'Unavailable',
|
265
|
+
'This application is not currently available',
|
266
|
+
'InsufficientInstanceCapacity'
|
267
267
|
]
|
268
268
|
@@amazon_problems = AMAZON_PROBLEMS
|
269
269
|
# Returns a list of Amazon service responses which are known to be transient problems.
|
@@ -284,7 +284,7 @@ module Aws
|
|
284
284
|
module AwsBaseInterface
|
285
285
|
DEFAULT_SIGNATURE_VERSION = '2'
|
286
286
|
|
287
|
-
@@caching
|
287
|
+
@@caching = false
|
288
288
|
|
289
289
|
def self.caching
|
290
290
|
@@caching
|
@@ -319,21 +319,21 @@ module Aws
|
|
319
319
|
@params = params
|
320
320
|
raise AwsError.new("AWS access keys are required to operate on #{service_info[:name]}") \
|
321
321
|
if aws_access_key_id.blank? || aws_secret_access_key.blank?
|
322
|
-
@aws_access_key_id
|
322
|
+
@aws_access_key_id = aws_access_key_id
|
323
323
|
@aws_secret_access_key = aws_secret_access_key
|
324
324
|
# if the endpoint was explicitly defined - then use it
|
325
325
|
if @params[:endpoint_url]
|
326
|
-
@params[:server]
|
327
|
-
@params[:port]
|
328
|
-
@params[:service]
|
326
|
+
@params[:server] = URI.parse(@params[:endpoint_url]).host
|
327
|
+
@params[:port] = URI.parse(@params[:endpoint_url]).port
|
328
|
+
@params[:service] = URI.parse(@params[:endpoint_url]).path
|
329
329
|
@params[:protocol] = URI.parse(@params[:endpoint_url]).scheme
|
330
|
-
@params[:region]
|
330
|
+
@params[:region] = nil
|
331
331
|
else
|
332
332
|
@params[:server] ||= service_info[:default_host]
|
333
333
|
@params[:server] = "#{@params[:region]}.#{@params[:server]}" if @params[:region]
|
334
|
-
@params[:port]
|
335
|
-
@params[:service]
|
336
|
-
@params[:protocol]
|
334
|
+
@params[:port] ||= service_info[:default_port]
|
335
|
+
@params[:service] ||= service_info[:default_service]
|
336
|
+
@params[:protocol] ||= service_info[:default_protocol]
|
337
337
|
@params[:api_version] ||= service_info[:api_version]
|
338
338
|
end
|
339
339
|
if !@params[:multi_thread].nil? && @params[:connection_mode].nil? # user defined this
|
@@ -347,12 +347,12 @@ module Aws
|
|
347
347
|
@logger = ::Rails.logger if !@logger && defined?(::Rails.logger)
|
348
348
|
@logger = Logger.new(STDOUT) if !@logger
|
349
349
|
@logger.info "New #{self.class.name} using #{@params[:connection_mode].to_s}-connection mode"
|
350
|
-
@error_handler
|
351
|
-
@cache
|
350
|
+
@error_handler = nil
|
351
|
+
@cache = {}
|
352
352
|
@signature_version = (params[:signature_version] || DEFAULT_SIGNATURE_VERSION).to_s
|
353
353
|
end
|
354
354
|
|
355
|
-
def signed_service_params(aws_secret_access_key, service_hash, http_verb=nil, host=nil, service=nil
|
355
|
+
def signed_service_params(aws_secret_access_key, service_hash, http_verb=nil, host=nil, service=nil)
|
356
356
|
case signature_version.to_s
|
357
357
|
when '0' then
|
358
358
|
AwsUtils::sign_request_v0(aws_secret_access_key, service_hash)
|
@@ -371,18 +371,18 @@ module Aws
|
|
371
371
|
end
|
372
372
|
|
373
373
|
# FROM SDB
|
374
|
-
def generate_request2(aws_access_key, aws_secret_key, action, api_version, lib_params, user_params={}) #:nodoc:
|
374
|
+
def generate_request2(aws_access_key, aws_secret_key, action, api_version, lib_params, user_params={}, options={}) #:nodoc:
|
375
375
|
# remove empty params from request
|
376
|
-
user_params.delete_if {|key, value| value.nil? }
|
376
|
+
user_params.delete_if { |key, value| value.nil? }
|
377
377
|
# user_params.each_pair do |k,v|
|
378
378
|
# user_params[k] = v.force_encoding("UTF-8")
|
379
379
|
# end
|
380
380
|
#params_string = params.to_a.collect{|key,val| key + "=#{CGI::escape(val.to_s)}" }.join("&")
|
381
381
|
# prepare service data
|
382
|
-
service
|
382
|
+
service = lib_params[:service]
|
383
383
|
# puts 'service=' + service.to_s
|
384
384
|
service_hash = {"Action" => action,
|
385
|
-
"AWSAccessKeyId" => aws_access_key
|
385
|
+
"AWSAccessKeyId" => aws_access_key}
|
386
386
|
service_hash.update("Version" => api_version) if api_version
|
387
387
|
service_hash.update(user_params)
|
388
388
|
service_params = signed_service_params(aws_secret_key, service_hash, :get, lib_params[:server], lib_params[:service])
|
@@ -394,8 +394,8 @@ module Aws
|
|
394
394
|
# resign the request because HTTP verb is included into signature
|
395
395
|
service_params = signed_service_params(aws_secret_key, service_hash, :post, lib_params[:server], service)
|
396
396
|
end
|
397
|
-
request
|
398
|
-
request.body
|
397
|
+
request = Net::HTTP::Post.new(service)
|
398
|
+
request.body = service_params
|
399
399
|
request['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
400
400
|
else
|
401
401
|
request = Net::HTTP::Get.new("#{service}?#{service_params}")
|
@@ -405,10 +405,10 @@ module Aws
|
|
405
405
|
#puts "#{@params[:service]}?#{service_params}\n\n"
|
406
406
|
|
407
407
|
# prepare output hash
|
408
|
-
{
|
409
|
-
|
410
|
-
|
411
|
-
|
408
|
+
{:request => request,
|
409
|
+
:server => lib_params[:server],
|
410
|
+
:port => lib_params[:port],
|
411
|
+
:protocol => lib_params[:protocol]}
|
412
412
|
end
|
413
413
|
|
414
414
|
def get_conn(connection_name, lib_params, logger)
|
@@ -422,9 +422,9 @@ module Aws
|
|
422
422
|
http_conn = Rightscale::HttpConnection.new(:exception => AwsError, :logger => logger)
|
423
423
|
|
424
424
|
elsif conn_mode == :per_thread || conn_mode == :single
|
425
|
-
thread
|
425
|
+
thread = conn_mode == :per_thread ? Thread.current : Thread.main
|
426
426
|
thread[connection_name] ||= Rightscale::HttpConnection.new(:exception => AwsError, :logger => logger)
|
427
|
-
http_conn
|
427
|
+
http_conn = thread[connection_name]
|
428
428
|
# ret = request_info_impl(http_conn, bench, request, parser, &block)
|
429
429
|
end
|
430
430
|
return http_conn
|
@@ -450,16 +450,17 @@ module Aws
|
|
450
450
|
|
451
451
|
# Sends request to Amazon and parses the response
|
452
452
|
# Raises AwsError if any banana happened
|
453
|
-
def request_info2(request, parser, lib_params, connection_name, logger, bench, &block)
|
454
|
-
ret
|
453
|
+
def request_info2(request, parser, lib_params, connection_name, logger, bench, options={}, &block) #:nodoc:
|
454
|
+
ret = nil
|
455
|
+
# puts 'OPTIONS=' + options.inspect
|
455
456
|
http_conn = get_conn(connection_name, lib_params, logger)
|
456
457
|
begin
|
457
458
|
retry_count = 1
|
458
|
-
count
|
459
|
+
count = 0
|
459
460
|
while count <= retry_count
|
460
461
|
puts 'RETRYING QUERY due to QueryTimeout...' if count > 0
|
461
462
|
begin
|
462
|
-
ret = request_info_impl(http_conn, bench, request, parser, &block)
|
463
|
+
ret = request_info_impl(http_conn, bench, request, parser, options, &block)
|
463
464
|
break
|
464
465
|
rescue Aws::AwsError => ex
|
465
466
|
if !ex.include?(/QueryTimeout/) || count == retry_count
|
@@ -484,19 +485,19 @@ module Aws
|
|
484
485
|
|
485
486
|
@connection = get_conn(connection_name, lib_params, logger)
|
486
487
|
begin
|
487
|
-
@last_request
|
488
|
+
@last_request = request[:request]
|
488
489
|
@last_response = nil
|
489
490
|
|
490
|
-
response
|
491
|
+
response = @connection.request(request)
|
491
492
|
# puts "response=" + response.body
|
492
493
|
# benchblock.service.add!{ response = @connection.request(request) }
|
493
494
|
# check response for errors...
|
494
495
|
@last_response = response
|
495
496
|
if response.is_a?(Net::HTTPSuccess)
|
496
|
-
@error_handler
|
497
|
+
@error_handler = nil
|
497
498
|
# benchblock.xml.add! { parser.parse(response) }
|
498
499
|
# return parser.result
|
499
|
-
force_array
|
500
|
+
force_array = params[:force_array] || false
|
500
501
|
# Force_array and group_tags don't work nice together so going to force array manually
|
501
502
|
xml_simple_options = {"KeyToSymbol"=>false, 'ForceArray' => false}
|
502
503
|
xml_simple_options["GroupTags"] = params[:group_tags] if params[:group_tags]
|
@@ -517,7 +518,7 @@ module Aws
|
|
517
518
|
parsed = symbolize(parsed, force_array)
|
518
519
|
# puts 'parsed=' + parsed.inspect
|
519
520
|
if params[:pull_out_array]
|
520
|
-
ret
|
521
|
+
ret = Aws::AwsResponseArray.new(parsed[:response_metadata])
|
521
522
|
level_hash = parsed
|
522
523
|
params[:pull_out_array].each do |x|
|
523
524
|
level_hash = level_hash[x]
|
@@ -532,7 +533,7 @@ module Aws
|
|
532
533
|
end
|
533
534
|
elsif params[:pull_out_single]
|
534
535
|
# returns a single object
|
535
|
-
ret
|
536
|
+
ret = AwsResponseObjectHash.new(parsed[:response_metadata])
|
536
537
|
level_hash = parsed
|
537
538
|
params[:pull_out_single].each do |x|
|
538
539
|
level_hash = level_hash[x]
|
@@ -589,17 +590,17 @@ module Aws
|
|
589
590
|
def cache_hits?(function, response, do_raise=:raise)
|
590
591
|
result = false
|
591
592
|
if caching?
|
592
|
-
function
|
593
|
+
function = function.to_sym
|
593
594
|
# get rid of requestId (this bad boy was added for API 2008-08-08+ and it is uniq for every response)
|
594
|
-
response
|
595
|
+
response = response.sub(%r{<requestId>.+?</requestId>}, '')
|
595
596
|
response_md5 =Digest::MD5.hexdigest(response).to_s
|
596
597
|
# check for changes
|
597
598
|
unless @cache[function] && @cache[function][:response_md5] == response_md5
|
598
599
|
# well, the response is new, reset cache data
|
599
600
|
update_cache(function, {:response_md5 => response_md5,
|
600
|
-
:timestamp
|
601
|
-
:hits
|
602
|
-
:parsed
|
601
|
+
:timestamp => Time.now,
|
602
|
+
:hits => 0,
|
603
|
+
:parsed => nil})
|
603
604
|
else
|
604
605
|
# aha, cache hits, update the data and throw an exception if needed
|
605
606
|
@cache[function][:hits] += 1
|
@@ -630,13 +631,15 @@ module Aws
|
|
630
631
|
end
|
631
632
|
|
632
633
|
|
633
|
-
def request_info_impl(connection, benchblock, request, parser, &block) #:nodoc:
|
634
|
-
@connection
|
635
|
-
@last_request
|
634
|
+
def request_info_impl(connection, benchblock, request, parser, options={}, &block) #:nodoc:
|
635
|
+
@connection = connection
|
636
|
+
@last_request = request[:request]
|
636
637
|
@last_response = nil
|
637
|
-
response=nil
|
638
|
+
response =nil
|
638
639
|
blockexception = nil
|
639
640
|
|
641
|
+
# puts 'OPTIONS2=' + options.inspect
|
642
|
+
|
640
643
|
if (block != nil)
|
641
644
|
# TRB 9/17/07 Careful - because we are passing in blocks, we get a situation where
|
642
645
|
# an exception may get thrown in the block body (which is high-level
|
@@ -655,7 +658,7 @@ module Aws
|
|
655
658
|
response.read_body(&block)
|
656
659
|
else
|
657
660
|
@error_handler = AWSErrorHandler.new(self, parser, :errors_list => self.class.amazon_problems) unless @error_handler
|
658
|
-
check_result = @error_handler.check(request)
|
661
|
+
check_result = @error_handler.check(request, options)
|
659
662
|
if check_result
|
660
663
|
@error_handler = nil
|
661
664
|
return check_result
|
@@ -679,7 +682,7 @@ module Aws
|
|
679
682
|
return parser.result
|
680
683
|
end
|
681
684
|
else
|
682
|
-
benchblock.service.add!{ response = @connection.request(request) }
|
685
|
+
benchblock.service.add! { response = @connection.request(request) }
|
683
686
|
# check response for errors...
|
684
687
|
@last_response = response
|
685
688
|
if response.is_a?(Net::HTTPSuccess)
|
@@ -688,7 +691,7 @@ module Aws
|
|
688
691
|
return parser.result
|
689
692
|
else
|
690
693
|
@error_handler = AWSErrorHandler.new(self, parser, :errors_list => self.class.amazon_problems) unless @error_handler
|
691
|
-
check_result = @error_handler.check(request)
|
694
|
+
check_result = @error_handler.check(request, options)
|
692
695
|
if check_result
|
693
696
|
@error_handler = nil
|
694
697
|
return check_result
|
@@ -711,7 +714,7 @@ module Aws
|
|
711
714
|
response, params = request_info(link, RightDummyParser.new)
|
712
715
|
cache_hits?(method.to_sym, response.body) if use_cache
|
713
716
|
parser = parser_class.new(:logger => @logger)
|
714
|
-
benchblock.xml.add!{ parser.parse(response, params) }
|
717
|
+
benchblock.xml.add! { parser.parse(response, params) }
|
715
718
|
result = block_given? ? yield(parser) : parser.result
|
716
719
|
# update parsed data
|
717
720
|
update_cache(method.to_sym, :parsed => result) if use_cache
|
@@ -725,7 +728,7 @@ module Aws
|
|
725
728
|
|
726
729
|
def hash_params(prefix, list) #:nodoc:
|
727
730
|
groups = {}
|
728
|
-
list.each_index{|i| groups.update("#{prefix}.#{i+1}"=>list[i])} if list
|
731
|
+
list.each_index { |i| groups.update("#{prefix}.#{i+1}"=>list[i]) } if list
|
729
732
|
return groups
|
730
733
|
end
|
731
734
|
|
@@ -754,12 +757,12 @@ module Aws
|
|
754
757
|
attr_reader :response
|
755
758
|
|
756
759
|
def initialize(errors=nil, http_code=nil, request_id=nil, request_data=nil, response=nil)
|
757
|
-
@errors
|
758
|
-
@request_id
|
759
|
-
@http_code
|
760
|
+
@errors = errors
|
761
|
+
@request_id = request_id
|
762
|
+
@http_code = http_code
|
760
763
|
@request_data = request_data
|
761
|
-
@response
|
762
|
-
msg
|
764
|
+
@response = response
|
765
|
+
msg = @errors.is_a?(Array) ? @errors.map { |code, msg| "#{code}: #{msg}" }.join("; ") : @errors.to_s
|
763
766
|
msg += "\nREQUEST=#{@request_data} " unless @request_data.nil?
|
764
767
|
msg += "\nREQUEST ID=#{@request_id} " unless @request_id.nil?
|
765
768
|
super(msg)
|
@@ -769,7 +772,7 @@ module Aws
|
|
769
772
|
# Used to determine whether to retry request.
|
770
773
|
def include?(pattern)
|
771
774
|
if @errors.is_a?(Array)
|
772
|
-
@errors.each{ |code, msg| return true if code =~ pattern }
|
775
|
+
@errors.each { |code, msg| return true if code =~ pattern }
|
773
776
|
else
|
774
777
|
return true if @errors_str =~ pattern
|
775
778
|
end
|
@@ -789,8 +792,8 @@ module Aws
|
|
789
792
|
puts error_text if options[:puts]
|
790
793
|
# Log the error
|
791
794
|
if options[:log]
|
792
|
-
request
|
793
|
-
response
|
795
|
+
request = aws.last_request ? aws.last_request.path : '-none-'
|
796
|
+
response = aws.last_response ? "#{aws.last_response.code} -- #{aws.last_response.message} -- #{aws.last_response.body}" : '-none-'
|
794
797
|
@response = response
|
795
798
|
aws.logger.error error_text
|
796
799
|
aws.logger.error "Request was: #{request}"
|
@@ -826,14 +829,14 @@ module Aws
|
|
826
829
|
|
827
830
|
def initialize(http_code=nil, request_id=nil, request_data=nil, response=nil)
|
828
831
|
|
829
|
-
@request_id
|
830
|
-
@http_code
|
832
|
+
@request_id = request_id
|
833
|
+
@http_code = http_code
|
831
834
|
@request_data = request_data
|
832
|
-
@response
|
835
|
+
@response = response
|
833
836
|
# puts '@response=' + @response.inspect
|
834
837
|
|
835
838
|
if @response
|
836
|
-
ref = XmlSimple.xml_in(@response, {
|
839
|
+
ref = XmlSimple.xml_in(@response, {"ForceArray"=>false})
|
837
840
|
# puts "refxml=" + ref.inspect
|
838
841
|
msg = "#{ref['Error']['Code']}: #{ref['Error']['Message']}"
|
839
842
|
else
|
@@ -851,7 +854,7 @@ module Aws
|
|
851
854
|
# 0-100 (%)
|
852
855
|
DEFAULT_CLOSE_ON_4XX_PROBABILITY = 10
|
853
856
|
|
854
|
-
@@reiteration_start_delay
|
857
|
+
@@reiteration_start_delay = 0.2
|
855
858
|
|
856
859
|
def self.reiteration_start_delay
|
857
860
|
@@reiteration_start_delay
|
@@ -897,26 +900,26 @@ module Aws
|
|
897
900
|
# :close_on_error = true | false
|
898
901
|
# :close_on_4xx_probability = 1-100
|
899
902
|
def initialize(aws, parser, params={}) #:nodoc:
|
900
|
-
@aws
|
901
|
-
@parser
|
902
|
-
@started_at
|
903
|
-
@stop_at
|
904
|
-
@errors_list
|
905
|
-
@reiteration_delay
|
906
|
-
@retries
|
903
|
+
@aws = aws # Link to RightEc2 | RightSqs | RightS3 instance
|
904
|
+
@parser = parser # parser to parse Amazon response
|
905
|
+
@started_at = Time.now
|
906
|
+
@stop_at = @started_at + (params[:reiteration_time] || @@reiteration_time)
|
907
|
+
@errors_list = params[:errors_list] || []
|
908
|
+
@reiteration_delay = @@reiteration_start_delay
|
909
|
+
@retries = 0
|
907
910
|
# close current HTTP(S) connection on 5xx, errors from list and 4xx errors
|
908
|
-
@close_on_error
|
911
|
+
@close_on_error = params[:close_on_error].nil? ? @@close_on_error : params[:close_on_error]
|
909
912
|
@close_on_4xx_probability = params[:close_on_4xx_probability] || @@close_on_4xx_probability
|
910
913
|
end
|
911
914
|
|
912
915
|
# Returns false if
|
913
|
-
def check(request) #:nodoc:
|
914
|
-
result
|
915
|
-
error_found
|
916
|
-
redirect_detected= false
|
917
|
-
error_match
|
918
|
-
last_errors_text
|
919
|
-
response
|
916
|
+
def check(request, options={}) #:nodoc:
|
917
|
+
result = false
|
918
|
+
error_found = false
|
919
|
+
redirect_detected = false
|
920
|
+
error_match = nil
|
921
|
+
last_errors_text = ''
|
922
|
+
response = @aws.last_response
|
920
923
|
# log error
|
921
924
|
request_text_data = "#{request[:server]}:#{request[:port]}#{request[:request].path}"
|
922
925
|
# is this a redirect?
|
@@ -933,9 +936,9 @@ module Aws
|
|
933
936
|
@aws.class.bench_xml.add! do
|
934
937
|
error_parser = RightErrorResponseParser.new
|
935
938
|
error_parser.parse(response)
|
936
|
-
@aws.last_errors
|
939
|
+
@aws.last_errors = error_parser.errors
|
937
940
|
@aws.last_request_id = error_parser.requestID
|
938
|
-
last_errors_text
|
941
|
+
last_errors_text = @aws.last_errors.flatten.join("\n")
|
939
942
|
# on redirect :
|
940
943
|
if redirect_detected
|
941
944
|
location = response['location']
|
@@ -943,15 +946,15 @@ module Aws
|
|
943
946
|
@aws.logger.info("##### #{@aws.class.name} redirect requested: #{response.code} #{response.message} #####")
|
944
947
|
@aws.logger.info("##### New location: #{location} #####")
|
945
948
|
# ... fix the connection data
|
946
|
-
request[:server]
|
949
|
+
request[:server] = URI.parse(location).host
|
947
950
|
request[:protocol] = URI.parse(location).scheme
|
948
|
-
request[:port]
|
951
|
+
request[:port] = URI.parse(location).port
|
949
952
|
end
|
950
953
|
end
|
951
954
|
else # ... it is not a xml document(probably just a html page?)
|
952
|
-
@aws.last_errors
|
955
|
+
@aws.last_errors = [[response.code, "#{response.message} (#{request_text_data})"]]
|
953
956
|
@aws.last_request_id = '-undefined-'
|
954
|
-
last_errors_text
|
957
|
+
last_errors_text = response.message
|
955
958
|
end
|
956
959
|
# now - check the error
|
957
960
|
unless redirect_detected
|
@@ -972,30 +975,34 @@ module Aws
|
|
972
975
|
if !redirect_detected && @close_on_error
|
973
976
|
@aws.connection.finish "#{self.class.name}: error match to pattern '#{error_match}'"
|
974
977
|
end
|
975
|
-
|
976
|
-
if
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
978
|
+
# puts 'OPTIONS3=' + options.inspect
|
979
|
+
if options[:retries].nil? || @retries < options[:retries]
|
980
|
+
if (Time.now < @stop_at)
|
981
|
+
@retries += 1
|
982
|
+
unless redirect_detected
|
983
|
+
@aws.logger.warn("##### Retry ##{@retries} is being performed. Sleeping for #{@reiteration_delay} sec. Whole time: #{Time.now-@started_at} sec ####")
|
984
|
+
sleep @reiteration_delay
|
985
|
+
@reiteration_delay *= 2
|
986
|
+
|
987
|
+
# Always make sure that the fp is set to point to the beginning(?)
|
988
|
+
# of the File/IO. TODO: it assumes that offset is 0, which is bad.
|
989
|
+
if (request[:request].body_stream && request[:request].body_stream.respond_to?(:pos))
|
990
|
+
begin
|
991
|
+
request[:request].body_stream.pos = 0
|
992
|
+
rescue Exception => e
|
993
|
+
@logger.warn("Retry may fail due to unable to reset the file pointer" +
|
994
|
+
" -- #{self.class.name} : #{e.inspect}")
|
995
|
+
end
|
991
996
|
end
|
997
|
+
else
|
998
|
+
@aws.logger.info("##### Retry ##{@retries} is being performed due to a redirect. ####")
|
992
999
|
end
|
1000
|
+
result = @aws.request_info(request, @parser, options)
|
993
1001
|
else
|
994
|
-
@aws.logger.
|
1002
|
+
@aws.logger.warn("##### Ooops, time is over... ####")
|
995
1003
|
end
|
996
|
-
result = @aws.request_info(request, @parser)
|
997
1004
|
else
|
998
|
-
@aws.logger.
|
1005
|
+
@aws.logger.info("##### Stopped retrying because retries=#{@retries} and max=#{options[:retries]} ####")
|
999
1006
|
end
|
1000
1007
|
# aha, this is unhandled error:
|
1001
1008
|
elsif @close_on_error
|
@@ -1005,7 +1012,7 @@ module Aws
|
|
1005
1012
|
# Is this a 4xx error ?
|
1006
1013
|
elsif @aws.last_response.code.to_s[/^4\d\d$/] && @close_on_4xx_probability > rand(100)
|
1007
1014
|
@aws.connection.finish "#{self.class.name}: code: #{@aws.last_response.code}: '#{@aws.last_response.message}', " +
|
1008
|
-
|
1015
|
+
"probability: #{@close_on_4xx_probability}%"
|
1009
1016
|
end
|
1010
1017
|
end
|
1011
1018
|
result
|
@@ -1058,11 +1065,11 @@ module Aws
|
|
1058
1065
|
|
1059
1066
|
class AwsParser #:nodoc:
|
1060
1067
|
# default parsing library
|
1061
|
-
DEFAULT_XML_LIBRARY
|
1068
|
+
DEFAULT_XML_LIBRARY = 'rexml'
|
1062
1069
|
# a list of supported parsers
|
1063
1070
|
@@supported_xml_libs = [DEFAULT_XML_LIBRARY, 'libxml']
|
1064
1071
|
|
1065
|
-
@@xml_lib
|
1072
|
+
@@xml_lib = DEFAULT_XML_LIBRARY # xml library name: 'rexml' | 'libxml'
|
1066
1073
|
def self.xml_lib
|
1067
1074
|
@@xml_lib
|
1068
1075
|
end
|
@@ -1077,10 +1084,10 @@ module Aws
|
|
1077
1084
|
|
1078
1085
|
def initialize(params={})
|
1079
1086
|
@xmlpath = ''
|
1080
|
-
@result
|
1081
|
-
@text
|
1087
|
+
@result = false
|
1088
|
+
@text = ''
|
1082
1089
|
@xml_lib = params[:xml_lib] || @@xml_lib
|
1083
|
-
@logger
|
1090
|
+
@logger = params[:logger]
|
1084
1091
|
reset
|
1085
1092
|
end
|
1086
1093
|
|
@@ -1141,9 +1148,9 @@ module Aws
|
|
1141
1148
|
if XML::Parser::VERSION >= '0.5.1.0'
|
1142
1149
|
xml.callbacks = RightSaxParserCallback.new(self)
|
1143
1150
|
else
|
1144
|
-
xml.on_start_element{|name, attr_hash| self.tag_start(name, attr_hash)}
|
1145
|
-
xml.on_characters{ |text| self.text(text)}
|
1146
|
-
xml.on_end_element{ |name| self.tag_end(name)}
|
1151
|
+
xml.on_start_element { |name, attr_hash| self.tag_start(name, attr_hash) }
|
1152
|
+
xml.on_characters { |text| self.text(text) }
|
1153
|
+
xml.on_end_element { |name| self.tag_end(name) }
|
1147
1154
|
end
|
1148
1155
|
xml.parse
|
1149
1156
|
else
|
@@ -1210,7 +1217,7 @@ module Aws
|
|
1210
1217
|
# when 'HostId' ; @host_id = @text
|
1211
1218
|
# when 'Bucket' ; @bucket = @text
|
1212
1219
|
when 'Error';
|
1213
|
-
@errors << [
|
1220
|
+
@errors << [@code, @message]
|
1214
1221
|
end
|
1215
1222
|
end
|
1216
1223
|
|
@@ -29,17 +29,17 @@ module Aws
|
|
29
29
|
|
30
30
|
include AwsBaseInterface
|
31
31
|
|
32
|
-
DEFAULT_HOST
|
33
|
-
DEFAULT_PORT
|
34
|
-
DEFAULT_PROTOCOL
|
35
|
-
DEFAULT_SERVICE
|
36
|
-
REQUEST_TTL
|
37
|
-
DEFAULT_EXPIRES_AFTER
|
38
|
-
ONE_YEAR_IN_SECONDS
|
39
|
-
AMAZON_HEADER_PREFIX
|
40
|
-
AMAZON_METADATA_PREFIX
|
41
|
-
|
42
|
-
@@bench
|
32
|
+
DEFAULT_HOST = 's3.amazonaws.com'
|
33
|
+
DEFAULT_PORT = 443
|
34
|
+
DEFAULT_PROTOCOL = 'https'
|
35
|
+
DEFAULT_SERVICE = '/'
|
36
|
+
REQUEST_TTL = 30
|
37
|
+
DEFAULT_EXPIRES_AFTER = 1 * 24 * 60 * 60 # One day's worth of seconds
|
38
|
+
ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60
|
39
|
+
AMAZON_HEADER_PREFIX = 'x-amz-'
|
40
|
+
AMAZON_METADATA_PREFIX = 'x-amz-meta-'
|
41
|
+
|
42
|
+
@@bench = AwsBenchmarkingBlock.new
|
43
43
|
|
44
44
|
def self.bench_xml
|
45
45
|
@@bench.xml
|
@@ -87,17 +87,17 @@ module Aws
|
|
87
87
|
#-----------------------------------------------------------------
|
88
88
|
# Produces canonical string for signing.
|
89
89
|
def canonical_string(method, path, headers={}, expires=nil) # :nodoc:
|
90
|
-
s3_headers
|
90
|
+
s3_headers = {}
|
91
91
|
headers.each do |key, value|
|
92
92
|
key = key.downcase
|
93
93
|
s3_headers[key] = value.join("").strip if key[/^#{AMAZON_HEADER_PREFIX}|^content-md5$|^content-type$|^date$/o]
|
94
94
|
end
|
95
95
|
s3_headers['content-type'] ||= ''
|
96
96
|
s3_headers['content-md5'] ||= ''
|
97
|
-
s3_headers['date']
|
98
|
-
s3_headers['date']
|
97
|
+
s3_headers['date'] = '' if s3_headers.has_key? 'x-amz-date'
|
98
|
+
s3_headers['date'] = expires if expires
|
99
99
|
# prepare output string
|
100
|
-
out_string
|
100
|
+
out_string = "#{method}\n"
|
101
101
|
s3_headers.sort { |a, b| a[0] <=> b[0] }.each do |key, value|
|
102
102
|
out_string << (key[/^#{AMAZON_HEADER_PREFIX}/o] ? "#{key}:#{value}\n" : "#{value}\n")
|
103
103
|
end
|
@@ -123,8 +123,8 @@ module Aws
|
|
123
123
|
|
124
124
|
def fetch_request_params(headers) #:nodoc:
|
125
125
|
# default server to use
|
126
|
-
server
|
127
|
-
service
|
126
|
+
server = @params[:server]
|
127
|
+
service = @params[:service].to_s
|
128
128
|
service.chop! if service[%r{/$}] # remove trailing '/' from service
|
129
129
|
# extract bucket name and check it's dns compartibility
|
130
130
|
headers[:url].to_s[%r{^([a-z0-9._-]*)(/[^?]*)?(\?.+)?}i]
|
@@ -148,22 +148,22 @@ module Aws
|
|
148
148
|
def generate_rest_request(method, headers) # :nodoc:
|
149
149
|
# calculate request data
|
150
150
|
server, path, path_to_sign = fetch_request_params(headers)
|
151
|
-
data
|
151
|
+
data = headers[:data]
|
152
152
|
# remove unset(==optional) and symbolyc keys
|
153
153
|
headers.each { |key, value| headers.delete(key) if (value.nil? || key.is_a?(Symbol)) }
|
154
154
|
#
|
155
|
-
headers['content-type']
|
156
|
-
headers['date']
|
155
|
+
headers['content-type'] ||= ''
|
156
|
+
headers['date'] = Time.now.httpdate
|
157
157
|
# create request
|
158
|
-
request
|
158
|
+
request = "Net::HTTP::#{method.capitalize}".constantize.new(path)
|
159
159
|
request.body = data if data
|
160
160
|
# set request headers and meta headers
|
161
161
|
headers.each { |key, value| request[key.to_s] = value }
|
162
162
|
#generate auth strings
|
163
|
-
auth_string
|
164
|
-
signature
|
163
|
+
auth_string = canonical_string(request.method, path_to_sign, request.to_hash)
|
164
|
+
signature = AwsUtils::sign(@aws_secret_access_key, auth_string)
|
165
165
|
# set other headers
|
166
|
-
request['Authorization']
|
166
|
+
request['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
|
167
167
|
# prepare output hash
|
168
168
|
{:request => request,
|
169
169
|
:server => server,
|
@@ -202,9 +202,12 @@ module Aws
|
|
202
202
|
# s3.create_bucket('my-awesome-bucket-eu', :location => :eu) #=> true
|
203
203
|
#
|
204
204
|
def create_bucket(bucket, headers={})
|
205
|
-
data
|
205
|
+
data = nil
|
206
206
|
unless headers[:location].blank?
|
207
|
-
data = "<CreateBucketConfiguration><LocationConstraint>#{headers[:location].to_s.upcase}</LocationConstraint></CreateBucketConfiguration>"
|
207
|
+
# data = "<CreateBucketConfiguration><LocationConstraint>#{headers[:location].to_s.upcase}</LocationConstraint></CreateBucketConfiguration>"
|
208
|
+
location = headers[:location].to_s
|
209
|
+
location.upcase! if location == 'eu'
|
210
|
+
data = "<CreateBucketConfiguration><LocationConstraint>#{location}</LocationConstraint></CreateBucketConfiguration>"
|
208
211
|
end
|
209
212
|
req_hash = generate_rest_request('PUT', headers.merge(:url=>bucket, :data => data))
|
210
213
|
request_info(req_hash, RightHttp2xxParser.new)
|
@@ -289,7 +292,7 @@ module Aws
|
|
289
292
|
# 'max-keys' => "5"}, ..., {...}]
|
290
293
|
#
|
291
294
|
def list_bucket(bucket, options={}, headers={})
|
292
|
-
bucket
|
295
|
+
bucket += '?'+options.map { |k, v| "#{k.to_s}=#{CGI::escape v.to_s}" }.join('&') unless options.blank?
|
293
296
|
req_hash = generate_rest_request('GET', headers.merge(:url=>bucket))
|
294
297
|
request_info(req_hash, S3ListBucketParser.new(:logger => @logger))
|
295
298
|
rescue
|
@@ -326,8 +329,8 @@ module Aws
|
|
326
329
|
def incrementally_list_bucket(bucket, options={}, headers={}, &block)
|
327
330
|
internal_options = options.symbolize_keys
|
328
331
|
begin
|
329
|
-
internal_bucket
|
330
|
-
internal_bucket
|
332
|
+
internal_bucket = bucket.dup
|
333
|
+
internal_bucket += '?'+internal_options.map { |k, v| "#{k.to_s}=#{CGI::escape v.to_s}" }.join('&') unless internal_options.blank?
|
331
334
|
req_hash = generate_rest_request('GET', headers.merge(:url=>internal_bucket))
|
332
335
|
response = request_info(req_hash, S3ImprovedListBucketParser.new(:logger => @logger))
|
333
336
|
there_are_more_keys = response[:is_truncated]
|
@@ -409,8 +412,8 @@ module Aws
|
|
409
412
|
if (data_size >= USE_100_CONTINUE_PUT_SIZE)
|
410
413
|
headers['expect'] = '100-continue'
|
411
414
|
end
|
412
|
-
req_hash
|
413
|
-
|
415
|
+
req_hash = generate_rest_request('PUT', headers.merge(:url =>"#{bucket}/#{CGI::escape key}", :data=>data,
|
416
|
+
'Content-Length' => data_size.to_s))
|
414
417
|
request_info(req_hash, RightHttp2xxParser.new)
|
415
418
|
rescue
|
416
419
|
on_exception
|
@@ -828,9 +831,9 @@ module Aws
|
|
828
831
|
# calculate request data
|
829
832
|
server, path, path_to_sign = fetch_request_params(headers)
|
830
833
|
# expiration time
|
831
|
-
expires
|
832
|
-
expires
|
833
|
-
expires
|
834
|
+
expires ||= DEFAULT_EXPIRES_AFTER
|
835
|
+
expires = Time.now.utc + expires if expires.is_a?(Fixnum) && (expires < ONE_YEAR_IN_SECONDS)
|
836
|
+
expires = expires.to_i
|
834
837
|
# remove unset(==optional) and symbolyc keys
|
835
838
|
headers.each { |key, value| headers.delete(key) if (value.nil? || key.is_a?(Symbol)) }
|
836
839
|
#generate auth strings
|
@@ -991,11 +994,11 @@ module Aws
|
|
991
994
|
def tagend(name)
|
992
995
|
case name
|
993
996
|
when 'ID';
|
994
|
-
@owner[:owner_id]
|
997
|
+
@owner[:owner_id] = @text
|
995
998
|
when 'DisplayName';
|
996
|
-
@owner[:owner_display_name]
|
999
|
+
@owner[:owner_display_name] = @text
|
997
1000
|
when 'Name';
|
998
|
-
@current_bucket[:name]
|
1001
|
+
@current_bucket[:name] = @text
|
999
1002
|
when 'CreationDate';
|
1000
1003
|
@current_bucket[:creation_date] = @text
|
1001
1004
|
when 'Bucket';
|
@@ -1019,34 +1022,34 @@ module Aws
|
|
1019
1022
|
case name
|
1020
1023
|
# service info
|
1021
1024
|
when 'Name';
|
1022
|
-
@service['name']
|
1025
|
+
@service['name'] = @text
|
1023
1026
|
when 'Prefix';
|
1024
|
-
@service['prefix']
|
1027
|
+
@service['prefix'] = @text
|
1025
1028
|
when 'Marker';
|
1026
|
-
@service['marker']
|
1029
|
+
@service['marker'] = @text
|
1027
1030
|
when 'MaxKeys';
|
1028
|
-
@service['max-keys']
|
1031
|
+
@service['max-keys'] = @text
|
1029
1032
|
when 'Delimiter';
|
1030
|
-
@service['delimiter']
|
1033
|
+
@service['delimiter'] = @text
|
1031
1034
|
when 'IsTruncated';
|
1032
1035
|
@service['is_truncated'] = (@text =~ /false/ ? false : true)
|
1033
1036
|
# key data
|
1034
1037
|
when 'Key';
|
1035
|
-
@current_key[:key]
|
1038
|
+
@current_key[:key] = @text
|
1036
1039
|
when 'LastModified';
|
1037
|
-
@current_key[:last_modified]
|
1040
|
+
@current_key[:last_modified] = @text
|
1038
1041
|
when 'ETag';
|
1039
|
-
@current_key[:e_tag]
|
1042
|
+
@current_key[:e_tag] = @text
|
1040
1043
|
when 'Size';
|
1041
|
-
@current_key[:size]
|
1044
|
+
@current_key[:size] = @text.to_i
|
1042
1045
|
when 'StorageClass';
|
1043
|
-
@current_key[:storage_class]
|
1046
|
+
@current_key[:storage_class] = @text
|
1044
1047
|
when 'ID';
|
1045
|
-
@current_key[:owner_id]
|
1048
|
+
@current_key[:owner_id] = @text
|
1046
1049
|
when 'DisplayName';
|
1047
1050
|
@current_key[:owner_display_name] = @text
|
1048
1051
|
when 'Contents';
|
1049
|
-
@current_key[:service]
|
1052
|
+
@current_key[:service] = @service; @result << @current_key
|
1050
1053
|
end
|
1051
1054
|
end
|
1052
1055
|
end
|
@@ -1071,35 +1074,35 @@ module Aws
|
|
1071
1074
|
case name
|
1072
1075
|
# service info
|
1073
1076
|
when 'Name';
|
1074
|
-
@result[:name]
|
1077
|
+
@result[:name] = @text
|
1075
1078
|
# Amazon uses the same tag for the search prefix and for the entries
|
1076
1079
|
# in common prefix...so use our simple flag to see which element
|
1077
1080
|
# we are parsing
|
1078
1081
|
when 'Prefix';
|
1079
1082
|
@in_common_prefixes ? @common_prefixes << @text : @result[:prefix] = @text
|
1080
1083
|
when 'Marker';
|
1081
|
-
@result[:marker]
|
1084
|
+
@result[:marker] = @text
|
1082
1085
|
when 'MaxKeys';
|
1083
|
-
@result[:max_keys]
|
1086
|
+
@result[:max_keys] = @text
|
1084
1087
|
when 'Delimiter';
|
1085
|
-
@result[:delimiter]
|
1088
|
+
@result[:delimiter] = @text
|
1086
1089
|
when 'IsTruncated';
|
1087
1090
|
@result[:is_truncated] = (@text =~ /false/ ? false : true)
|
1088
1091
|
when 'NextMarker';
|
1089
|
-
@result[:next_marker]
|
1092
|
+
@result[:next_marker] = @text
|
1090
1093
|
# key data
|
1091
1094
|
when 'Key';
|
1092
|
-
@current_key[:key]
|
1095
|
+
@current_key[:key] = @text
|
1093
1096
|
when 'LastModified';
|
1094
|
-
@current_key[:last_modified]
|
1097
|
+
@current_key[:last_modified] = @text
|
1095
1098
|
when 'ETag';
|
1096
|
-
@current_key[:e_tag]
|
1099
|
+
@current_key[:e_tag] = @text
|
1097
1100
|
when 'Size';
|
1098
|
-
@current_key[:size]
|
1101
|
+
@current_key[:size] = @text.to_i
|
1099
1102
|
when 'StorageClass';
|
1100
|
-
@current_key[:storage_class]
|
1103
|
+
@current_key[:storage_class] = @text
|
1101
1104
|
when 'ID';
|
1102
|
-
@current_key[:owner_id]
|
1105
|
+
@current_key[:owner_id] = @text
|
1103
1106
|
when 'DisplayName';
|
1104
1107
|
@current_key[:owner_display_name] = @text
|
1105
1108
|
when 'Contents';
|
@@ -1189,7 +1192,7 @@ module Aws
|
|
1189
1192
|
when 'LastModified' then
|
1190
1193
|
@result[:last_modified] = @text
|
1191
1194
|
when 'ETag' then
|
1192
|
-
@result[:e_tag]
|
1195
|
+
@result[:e_tag] = @text
|
1193
1196
|
end
|
1194
1197
|
end
|
1195
1198
|
end
|
@@ -1208,7 +1211,7 @@ module Aws
|
|
1208
1211
|
def headers_to_string(headers)
|
1209
1212
|
result = {}
|
1210
1213
|
headers.each do |key, value|
|
1211
|
-
value
|
1214
|
+
value = value[0] if value.is_a?(Array) && value.size<2
|
1212
1215
|
result[key] = value
|
1213
1216
|
end
|
1214
1217
|
result
|
@@ -88,16 +88,16 @@ module Aws
|
|
88
88
|
#-----------------------------------------------------------------
|
89
89
|
# Requests
|
90
90
|
#-----------------------------------------------------------------
|
91
|
-
def generate_request(action, params={}) #:nodoc:
|
92
|
-
generate_request2(@aws_access_key_id, @aws_secret_access_key, action, API_VERSION, @params, params)
|
91
|
+
def generate_request(action, params={}, options={}) #:nodoc:
|
92
|
+
generate_request2(@aws_access_key_id, @aws_secret_access_key, action, API_VERSION, @params, params, options)
|
93
93
|
end
|
94
94
|
|
95
95
|
|
96
96
|
# Sends request to Amazon and parses the response
|
97
97
|
# Raises AwsError if any banana happened
|
98
|
-
def request_info(request, parser) #:nodoc:
|
98
|
+
def request_info(request, parser, options={}) #:nodoc:
|
99
99
|
# request_info2(request, parser, :sdb_connection)
|
100
|
-
request_info2(request, parser, @params, :sdb_connection, @logger, @@bench)
|
100
|
+
request_info2(request, parser, @params, :sdb_connection, @logger, @@bench, options)
|
101
101
|
|
102
102
|
end
|
103
103
|
|
@@ -615,6 +615,11 @@ module Aws
|
|
615
615
|
# { "37df6c36-75b0-11dd-9557-001bfc466dd7"=> {"name"=>["Mary"], "country"=>["USA"]} } ],
|
616
616
|
# :box_usage=>"0.0000777663"}
|
617
617
|
#
|
618
|
+
# options:
|
619
|
+
# :next_token
|
620
|
+
# :consistent_read
|
621
|
+
# :retries => maximum number of times to retry this query on an error response.
|
622
|
+
#
|
618
623
|
# see: http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDB_API_Select.html
|
619
624
|
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?UsingSelect.html
|
620
625
|
# http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?SDBLimits.html
|
@@ -622,12 +627,20 @@ module Aws
|
|
622
627
|
def select(select_expression, next_token = nil, consistent_read = nil)
|
623
628
|
select_expression = query_expression_from_array(select_expression) if select_expression.is_a?(Array)
|
624
629
|
@last_query_expression = select_expression
|
630
|
+
|
631
|
+
options = {}
|
632
|
+
if next_token.is_a?(Hash)
|
633
|
+
options = next_token
|
634
|
+
next_token = options[:next_token]
|
635
|
+
consistent_read = options[:consistent_read]
|
636
|
+
end
|
637
|
+
|
625
638
|
#
|
626
639
|
request_params = { 'SelectExpression' => select_expression,
|
627
640
|
'NextToken' => next_token,
|
628
641
|
'ConsistentRead' => consistent_read }
|
629
|
-
link = generate_request("Select", request_params)
|
630
|
-
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
642
|
+
link = generate_request("Select", request_params, options)
|
643
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new, options ))
|
631
644
|
return result unless block_given?
|
632
645
|
# loop if block if given
|
633
646
|
begin
|
@@ -636,7 +649,7 @@ module Aws
|
|
636
649
|
# make new request
|
637
650
|
request_params['NextToken'] = result[:next_token]
|
638
651
|
link = generate_request("Select", request_params)
|
639
|
-
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new ))
|
652
|
+
result = select_response_to_ruby(request_info( link, QSdbSelectParser.new, options ))
|
640
653
|
end while true
|
641
654
|
rescue Exception
|
642
655
|
on_exception
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 2.3.
|
8
|
+
- 27
|
9
|
+
version: 2.3.27
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Travis Reeder
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-12-02 00:00:00 -08:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -123,8 +123,8 @@ homepage: http://github.com/appoxy/aws/
|
|
123
123
|
licenses: []
|
124
124
|
|
125
125
|
post_install_message:
|
126
|
-
rdoc_options:
|
127
|
-
|
126
|
+
rdoc_options: []
|
127
|
+
|
128
128
|
require_paths:
|
129
129
|
- lib
|
130
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|