aws-sdk-core 2.0.3 → 2.0.4
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.
- checksums.yaml +4 -4
- data/apis/CognitoIdentity.api.json +16 -4
- data/apis/EC2.paginators.json +3 -0
- data/apis/ElastiCache.api.json +164 -15
- data/apis/IAM.api.json +326 -1
- data/apis/IAM.resources.json +2 -29
- data/apis/Route53Domains.api.json +56 -0
- data/apis/S3.api.json +1 -1
- data/endpoints.json +62 -76
- data/lib/aws-sdk-core.rb +4 -14
- data/lib/aws-sdk-core/api/documenter.rb +1 -1
- data/lib/aws-sdk-core/api/service_customizations.rb +1 -0
- data/lib/aws-sdk-core/assume_role_credentials.rb +46 -0
- data/lib/aws-sdk-core/autoscaling.rb +3 -3
- data/lib/aws-sdk-core/cloudformation.rb +3 -3
- data/lib/aws-sdk-core/cloudfront.rb +4 -4
- data/lib/aws-sdk-core/cloudsearch.rb +3 -3
- data/lib/aws-sdk-core/cloudsearchdomain.rb +2 -2
- data/lib/aws-sdk-core/cloudtrail.rb +3 -3
- data/lib/aws-sdk-core/cloudwatch.rb +3 -3
- data/lib/aws-sdk-core/cloudwatchlogs.rb +3 -3
- data/lib/aws-sdk-core/cognitoidentity.rb +2 -2
- data/lib/aws-sdk-core/cognitosync.rb +2 -2
- data/lib/aws-sdk-core/datapipeline.rb +3 -3
- data/lib/aws-sdk-core/directconnect.rb +3 -3
- data/lib/aws-sdk-core/dynamodb.rb +4 -4
- data/lib/aws-sdk-core/ec2.rb +5 -5
- data/lib/aws-sdk-core/elasticache.rb +3 -3
- data/lib/aws-sdk-core/elasticbeanstalk.rb +3 -3
- data/lib/aws-sdk-core/elasticloadbalancing.rb +3 -3
- data/lib/aws-sdk-core/elastictranscoder.rb +4 -4
- data/lib/aws-sdk-core/emr.rb +3 -3
- data/lib/aws-sdk-core/endpoint_provider.rb +16 -78
- data/lib/aws-sdk-core/glacier.rb +5 -5
- data/lib/aws-sdk-core/iam.rb +4 -4
- data/lib/aws-sdk-core/importexport.rb +3 -3
- data/lib/aws-sdk-core/instance_profile_credentials.rb +13 -45
- data/lib/aws-sdk-core/kinesis.rb +3 -3
- data/lib/aws-sdk-core/opsworks.rb +4 -4
- data/lib/aws-sdk-core/pageable_response.rb +18 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +1 -5
- data/lib/aws-sdk-core/plugins/request_signer.rb +3 -9
- data/lib/aws-sdk-core/plugins/s3_region_detection.rb +157 -0
- data/lib/aws-sdk-core/plugins/stub_responses.rb +13 -1
- data/lib/aws-sdk-core/rds.rb +4 -4
- data/lib/aws-sdk-core/redshift.rb +4 -4
- data/lib/aws-sdk-core/refreshing_credentials.rb +73 -0
- data/lib/aws-sdk-core/route53.rb +3 -3
- data/lib/aws-sdk-core/route53domains.rb +2 -2
- data/lib/aws-sdk-core/s3.rb +24 -5
- data/lib/aws-sdk-core/s3/bucket_region_cache.rb +75 -0
- data/lib/aws-sdk-core/ses.rb +4 -4
- data/lib/aws-sdk-core/signers/v4.rb +1 -1
- data/lib/aws-sdk-core/simpledb.rb +3 -3
- data/lib/aws-sdk-core/sns.rb +4 -4
- data/lib/aws-sdk-core/sqs.rb +4 -4
- data/lib/aws-sdk-core/storagegateway.rb +3 -3
- data/lib/aws-sdk-core/sts.rb +2 -2
- data/lib/aws-sdk-core/support.rb +3 -3
- data/lib/aws-sdk-core/swf.rb +3 -3
- data/lib/aws-sdk-core/version.rb +1 -1
- metadata +6 -2
| @@ -0,0 +1,157 @@ | |
| 1 | 
            +
            module Aws
         | 
| 2 | 
            +
              module Plugins
         | 
| 3 | 
            +
                # This plugin is an implementation detail and may be modified.
         | 
| 4 | 
            +
                # @api private
         | 
| 5 | 
            +
                class S3RegionDetection < Seahorse::Client::Plugin
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  # Intentionally not documented - this should go away when all
         | 
| 8 | 
            +
                  # services support signature version 4 in every region.
         | 
| 9 | 
            +
                  option(:signature_version) do |cfg|
         | 
| 10 | 
            +
                    if S3.sigv2_region?(cfg.region)
         | 
| 11 | 
            +
                      's3'
         | 
| 12 | 
            +
                    else
         | 
| 13 | 
            +
                      'v4'
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  class Handler < Seahorse::Client::Handler
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    private
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    def new_hostname(context, region)
         | 
| 22 | 
            +
                      bucket = context.params[:bucket]
         | 
| 23 | 
            +
                      if region == 'us-east-1'
         | 
| 24 | 
            +
                        "#{bucket}.s3-external-1.amazonaws.com"
         | 
| 25 | 
            +
                      else
         | 
| 26 | 
            +
                        "#{bucket}.s3.#{region}.amazonaws.com"
         | 
| 27 | 
            +
                      end
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  class CachedBucketRegionHandler < Handler
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    def call(context)
         | 
| 35 | 
            +
                      if bucket = context.params[:bucket]
         | 
| 36 | 
            +
                        use_regional_endpoint_when_known(context, bucket)
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
                      @handler.call(context)
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    private
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def use_regional_endpoint_when_known(context, bucket)
         | 
| 44 | 
            +
                      cached_region = S3::BUCKET_REGIONS[bucket]
         | 
| 45 | 
            +
                      if cached_region && cached_region != context.config.region
         | 
| 46 | 
            +
                        context.http_request.endpoint.host = new_hostname(context, cached_region)
         | 
| 47 | 
            +
                        context[:sigv4_region] = cached_region
         | 
| 48 | 
            +
                        context[:signature_version] =
         | 
| 49 | 
            +
                          S3.sigv2_region?(cached_region) ? 's3' : 'v4'
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  class DetectRegionHandler < Handler
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    def call(context)
         | 
| 58 | 
            +
                      response = @handler.call(context)
         | 
| 59 | 
            +
                      handle_region_errors(response)
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    private
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    def handle_region_errors(response)
         | 
| 65 | 
            +
                      if requires_sigv4?(response)
         | 
| 66 | 
            +
                        detect_region_and_retry(response)
         | 
| 67 | 
            +
                      elsif wrong_sigv4_region?(response)
         | 
| 68 | 
            +
                        extract_body_region_and_retry(response.context)
         | 
| 69 | 
            +
                      elsif moved_permanently?(response) and dns_style?(response.context)
         | 
| 70 | 
            +
                        # region detection not supported for 301 moved permanently
         | 
| 71 | 
            +
                        # when using path style
         | 
| 72 | 
            +
                        detect_region_and_retry(response) else
         | 
| 73 | 
            +
                        response
         | 
| 74 | 
            +
                      end
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    def requires_sigv4?(resp)
         | 
| 78 | 
            +
                      resp.context.http_response.status_code == 400 &&
         | 
| 79 | 
            +
                      resp.context.http_response.body_contents.include?('Please use AWS4-HMAC-SHA256') &&
         | 
| 80 | 
            +
                      resp.context.http_response.body.respond_to?(:truncate)
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    def wrong_sigv4_region?(resp)
         | 
| 84 | 
            +
                      resp.context.http_response.status_code == 400 &&
         | 
| 85 | 
            +
                      resp.context.http_response.body_contents.match(/<Region>.+?<\/Region>/)
         | 
| 86 | 
            +
                    end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                    def moved_permanently?(resp)
         | 
| 89 | 
            +
                      resp.context.http_response.status_code == 301
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    def extract_body_region_and_retry(context)
         | 
| 93 | 
            +
                      actual_region = region_from_body(context)
         | 
| 94 | 
            +
                      updgrade_to_v4(context, actual_region)
         | 
| 95 | 
            +
                      log_warning(context, actual_region)
         | 
| 96 | 
            +
                      @handler.call(context)
         | 
| 97 | 
            +
                    end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    def region_from_body(context)
         | 
| 100 | 
            +
                      context.http_response.body_contents.match(/<Region>(.+?)<\/Region>/)[1]
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    def detect_region_and_retry(resp)
         | 
| 104 | 
            +
                      context = resp.context
         | 
| 105 | 
            +
                      updgrade_to_v4(context, 'us-east-1')
         | 
| 106 | 
            +
                      resp = @handler.call(context)
         | 
| 107 | 
            +
                      actual_region = region_from_location_header(context)
         | 
| 108 | 
            +
                      updgrade_to_v4(context, actual_region)
         | 
| 109 | 
            +
                      log_warning(context, actual_region)
         | 
| 110 | 
            +
                      @handler.call(context)
         | 
| 111 | 
            +
                    end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    def updgrade_to_v4(context, region)
         | 
| 114 | 
            +
                      bucket = context.params[:bucket]
         | 
| 115 | 
            +
                      context.http_response.body.truncate(0)
         | 
| 116 | 
            +
                      context.http_request.headers.delete('authorization')
         | 
| 117 | 
            +
                      context.http_request.headers.delete('x-amz-security-token')
         | 
| 118 | 
            +
                      context.http_request.endpoint.host = new_hostname(context, region)
         | 
| 119 | 
            +
                      signer = Signers::V4.new(context.config.credentials, 's3', region)
         | 
| 120 | 
            +
                      signer.sign(context.http_request)
         | 
| 121 | 
            +
                    end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                    def dns_style?(context)
         | 
| 124 | 
            +
                      bucket = context.params[:bucket]
         | 
| 125 | 
            +
                      context.http_request.endpoint.host.match(/^#{Regexp.escape(bucket)}\.s3/)
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                    def region_from_location_header(context)
         | 
| 129 | 
            +
                      location = context.http_response.headers['location']
         | 
| 130 | 
            +
                      location.match(/s3\.(.+?)\.amazonaws\.com/)[1]
         | 
| 131 | 
            +
                    end
         | 
| 132 | 
            +
             | 
| 133 | 
            +
                    def log_warning(context, actual_region)
         | 
| 134 | 
            +
                      S3::BUCKET_REGIONS[context.params[:bucket]] = actual_region
         | 
| 135 | 
            +
                      msg = "S3 client configured for #{context.config.region.inspect} " +
         | 
| 136 | 
            +
                        "but the bucket #{context.params[:bucket].inspect} is in " +
         | 
| 137 | 
            +
                        "#{actual_region.inspect}; Please configure the proper region " +
         | 
| 138 | 
            +
                        "to avoid multiple unecessary redirects and signing attempts"
         | 
| 139 | 
            +
                      if logger = context.config.logger
         | 
| 140 | 
            +
                        logger.warn(msg)
         | 
| 141 | 
            +
                      else
         | 
| 142 | 
            +
                        warn(msg)
         | 
| 143 | 
            +
                      end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                    end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                  end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                  # BEFORE the request is signed
         | 
| 150 | 
            +
                  handle(CachedBucketRegionHandler, step: :sign, priority: 60)
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  # AFTER the request is signed
         | 
| 153 | 
            +
                  handle(DetectRegionHandler, step: :sign, priority: 40)
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
              end
         | 
| 157 | 
            +
            end
         | 
| @@ -14,13 +14,25 @@ module Aws | |
| 14 14 |  | 
| 15 15 | 
             
                  option(:stub_responses, false)
         | 
| 16 16 |  | 
| 17 | 
            +
                  option(:region) do |config|
         | 
| 18 | 
            +
                    'stubbed-region' if config.stub_responses
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  option(:credentials) do |config|
         | 
| 22 | 
            +
                    if config.stub_responses
         | 
| 23 | 
            +
                      Credentials.new('stubbed-akid', 'stubbed-secret')
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 17 27 | 
             
                  def add_handlers(handlers, config)
         | 
| 18 28 | 
             
                    handlers.add(Handler, step: :send) if config.stub_responses
         | 
| 19 29 | 
             
                  end
         | 
| 20 30 |  | 
| 21 31 | 
             
                  def after_initialize(client)
         | 
| 22 32 | 
             
                    # disable retries when stubbing responses
         | 
| 23 | 
            -
                     | 
| 33 | 
            +
                    if client.config.stub_responses
         | 
| 34 | 
            +
                      client.handlers.remove(RetryErrors::Handler)
         | 
| 35 | 
            +
                    end
         | 
| 24 36 | 
             
                  end
         | 
| 25 37 |  | 
| 26 38 | 
             
                  class Handler < Seahorse::Client::Handler
         | 
    
        data/lib/aws-sdk-core/rds.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Aws.add_service(:RDS, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 5 | 
            -
              waiters: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'RDS.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'RDS.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'RDS.paginators.json'),
         | 
| 5 | 
            +
              waiters: File.join(Aws::API_DIR, 'RDS.waiters.json'),
         | 
| 6 6 | 
             
            })
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Aws.add_service(:Redshift, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 5 | 
            -
              waiters: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'Redshift.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'Redshift.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'Redshift.paginators.json'),
         | 
| 5 | 
            +
              waiters: File.join(Aws::API_DIR, 'Redshift.waiters.json'),
         | 
| 6 6 | 
             
            })
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            require 'thread'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Aws
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              # Base class used credential classes that can be refreshed. This
         | 
| 6 | 
            +
              # provides basic refresh logic in a thread-safe manor. Classes mixing in
         | 
| 7 | 
            +
              # this module are expected to implement a #refresh method that populates
         | 
| 8 | 
            +
              # the following instance variables:
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # * `@access_key_id`
         | 
| 11 | 
            +
              # * `@secret_access_key`
         | 
| 12 | 
            +
              # * `@session_token`
         | 
| 13 | 
            +
              # * `@expiration`
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              # @api private
         | 
| 16 | 
            +
              module RefreshingCredentials
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def initialize(options = {})
         | 
| 19 | 
            +
                  @mutex = Mutex.new
         | 
| 20 | 
            +
                  refresh
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # @return [String,nil]
         | 
| 24 | 
            +
                def access_key_id
         | 
| 25 | 
            +
                  refresh_if_near_expiration
         | 
| 26 | 
            +
                  @access_key_id
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # @return [String,nil]
         | 
| 30 | 
            +
                def secret_access_key
         | 
| 31 | 
            +
                  refresh_if_near_expiration
         | 
| 32 | 
            +
                  @secret_access_key
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # @return [String,nil]
         | 
| 36 | 
            +
                def session_token
         | 
| 37 | 
            +
                  refresh_if_near_expiration
         | 
| 38 | 
            +
                  @session_token
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                # @return [Time,nil]
         | 
| 42 | 
            +
                def expiration
         | 
| 43 | 
            +
                  refresh_if_near_expiration
         | 
| 44 | 
            +
                  @expiration
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # Refresh credentials.
         | 
| 48 | 
            +
                # @return [void]
         | 
| 49 | 
            +
                def refresh!
         | 
| 50 | 
            +
                  @mutex.synchronize { refresh }
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                private
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                # Refreshes instance metadata credentials if they are within
         | 
| 56 | 
            +
                # 5 minutes of expiration.
         | 
| 57 | 
            +
                def refresh_if_near_expiration
         | 
| 58 | 
            +
                  if near_expiration?
         | 
| 59 | 
            +
                    @mutex.synchronize do
         | 
| 60 | 
            +
                      refresh if near_expiration?
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def near_expiration?
         | 
| 66 | 
            +
                  if @expiration
         | 
| 67 | 
            +
                    # are we within 5 minutes of expiration?
         | 
| 68 | 
            +
                    (Time.now.to_i + 5 * 60) > @expiration.to_i
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
    
        data/lib/aws-sdk-core/route53.rb
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            Aws.add_service(:Route53, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'Route53.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'Route53.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'Route53.paginators.json'),
         | 
| 5 5 | 
             
            })
         | 
| @@ -1,4 +1,4 @@ | |
| 1 1 | 
             
            Aws.add_service(:Route53Domains, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'Route53Domains.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'Route53Domains.docs.json'),
         | 
| 4 4 | 
             
            })
         | 
    
        data/lib/aws-sdk-core/s3.rb
    CHANGED
    
    | @@ -1,13 +1,32 @@ | |
| 1 1 | 
             
            Aws.add_service(:S3, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 5 | 
            -
              resources: File.join(Aws:: | 
| 6 | 
            -
              waiters: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'S3.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'S3.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'S3.paginators.json'),
         | 
| 5 | 
            +
              resources: File.join(Aws::API_DIR, 'S3.resources.json'),
         | 
| 6 | 
            +
              waiters: File.join(Aws::API_DIR, 'S3.waiters.json'),
         | 
| 7 7 | 
             
            })
         | 
| 8 8 |  | 
| 9 9 | 
             
            module Aws
         | 
| 10 10 | 
             
              module S3
         | 
| 11 | 
            +
             | 
| 11 12 | 
             
                autoload :Presigner, 'aws-sdk-core/s3/presigner'
         | 
| 13 | 
            +
                autoload :BucketRegionCache, 'aws-sdk-core/s3/bucket_region_cache'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # A cache of discovered bucket regions. You can call `#bucket_added`
         | 
| 16 | 
            +
                # on this to be notified when you must configure the proper region
         | 
| 17 | 
            +
                # to access a bucket.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # This cache is considered an implementation detail.
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # @api private
         | 
| 22 | 
            +
                BUCKET_REGIONS = BucketRegionCache.new
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                # @param [String] region
         | 
| 25 | 
            +
                # @return [Boolean]
         | 
| 26 | 
            +
                # @api private
         | 
| 27 | 
            +
                def self.sigv2_region?(region)
         | 
| 28 | 
            +
                  Client.api.metadata('sigv2Regions').include?(region)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 12 31 | 
             
              end
         | 
| 13 32 | 
             
            end
         | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            require 'thread'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Aws
         | 
| 4 | 
            +
              module S3
         | 
| 5 | 
            +
                class BucketRegionCache
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def initialize
         | 
| 8 | 
            +
                    @regions = {}
         | 
| 9 | 
            +
                    @listeners = []
         | 
| 10 | 
            +
                    @mutex = Mutex.new
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  # Registers a block as a callback. This listener is called when a
         | 
| 14 | 
            +
                  # new bucket/region pair is added to the cache.
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  #     S3::BUCKET_REGIONS.bucket_added do |bucket_name, region_name|
         | 
| 17 | 
            +
                  #       # ...
         | 
| 18 | 
            +
                  #     end
         | 
| 19 | 
            +
                  #
         | 
| 20 | 
            +
                  # This happens when a request is made against the classic endpoint,
         | 
| 21 | 
            +
                  # "s3.amazonaws.com" and an error is returned requiring the request
         | 
| 22 | 
            +
                  # to be resent with Signature Version 4. At this point, multiple
         | 
| 23 | 
            +
                  # requests are made to discover the bucket region so that a v4
         | 
| 24 | 
            +
                  # signature can be generated.
         | 
| 25 | 
            +
                  #
         | 
| 26 | 
            +
                  # An application can register listeners here to avoid these extra
         | 
| 27 | 
            +
                  # requests in the future. By constructing an {S3::Client} with
         | 
| 28 | 
            +
                  # the proper region, a proper signature can be generated and redirects
         | 
| 29 | 
            +
                  # avoided.
         | 
| 30 | 
            +
                  # @return [void]
         | 
| 31 | 
            +
                  def bucket_added(&block)
         | 
| 32 | 
            +
                    if block
         | 
| 33 | 
            +
                      @mutex.synchronize { @listeners << block }
         | 
| 34 | 
            +
                    else
         | 
| 35 | 
            +
                      raise ArgumentError, 'missing required block'
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # @param [String] bucket_name
         | 
| 40 | 
            +
                  # @return [String,nil] Returns the cached region for the named bucket.
         | 
| 41 | 
            +
                  #   Returns `nil` if the bucket is not in the cache.
         | 
| 42 | 
            +
                  # @api private
         | 
| 43 | 
            +
                  def [](bucket_name)
         | 
| 44 | 
            +
                    @mutex.synchronize { @regions[bucket_name] }
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # Caches a bucket's region. Calling this method will trigger each
         | 
| 48 | 
            +
                  # of the {#bucket_added} listener callbacks.
         | 
| 49 | 
            +
                  # @param [String] bucket_name
         | 
| 50 | 
            +
                  # @param [String] region_name
         | 
| 51 | 
            +
                  # @return [void]
         | 
| 52 | 
            +
                  # @api private
         | 
| 53 | 
            +
                  def []=(bucket_name, region_name)
         | 
| 54 | 
            +
                    @mutex.synchronize do
         | 
| 55 | 
            +
                      @regions[bucket_name] = region_name
         | 
| 56 | 
            +
                      @listeners.each { |block| block.call(bucket_name, region_name) }
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  # @api private
         | 
| 61 | 
            +
                  def clear
         | 
| 62 | 
            +
                    @mutex.synchronize { @regions = {} }
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  # @return [Hash] Returns a hash of cached bucket names and region names.
         | 
| 66 | 
            +
                  def to_hash
         | 
| 67 | 
            +
                    @mutex.synchronize do
         | 
| 68 | 
            +
                      @regions.dup
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                  alias to_h to_hash
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
    
        data/lib/aws-sdk-core/ses.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Aws.add_service(:SES, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 5 | 
            -
              waiters: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'SES.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'SES.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'SES.paginators.json'),
         | 
| 5 | 
            +
              waiters: File.join(Aws::API_DIR, 'SES.waiters.json'),
         | 
| 6 6 | 
             
            })
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            Aws.add_service(:SimpleDB, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'SimpleDB.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'SimpleDB.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'SimpleDB.paginators.json'),
         | 
| 5 5 | 
             
            })
         | 
    
        data/lib/aws-sdk-core/sns.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Aws.add_service(:SNS, {
         | 
| 2 | 
            -
              api: File.join(Aws:: | 
| 3 | 
            -
              docs: File.join(Aws:: | 
| 4 | 
            -
              paginators: File.join(Aws:: | 
| 5 | 
            -
              resources: File.join(Aws:: | 
| 2 | 
            +
              api: File.join(Aws::API_DIR, 'SNS.api.json'),
         | 
| 3 | 
            +
              docs: File.join(Aws::API_DIR, 'SNS.docs.json'),
         | 
| 4 | 
            +
              paginators: File.join(Aws::API_DIR, 'SNS.paginators.json'),
         | 
| 5 | 
            +
              resources: File.join(Aws::API_DIR, 'SNS.resources.json'),
         | 
| 6 6 | 
             
            })
         |