aws-sdk-core 2.0.0.rc8 → 2.0.0.rc9
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/DynamoDB-2012-08-10.json +1 -0
 - data/apis/EC2-2014-05-01.json +15232 -0
 - data/apis/ElasticBeanstalk-2010-12-01.json +17 -0
 - data/apis/OpsWorks-2013-02-18.json +215 -0
 - data/apis/Redshift-2012-12-01.json +72 -0
 - data/apis/S3-2006-03-01.json +271 -15
 - data/apis/SNS-2010-03-31.json +27 -0
 - data/apis/source/ec2-2014-05-01.json +20662 -0
 - data/apis/source/ec2-2014-05-01.paginators.json +112 -0
 - data/apis/source/ec2-2014-05-01.waiters.json +146 -0
 - data/apis/source/elasticbeanstalk-2010-12-01.json +26 -0
 - data/apis/source/opsworks-2013-02-18.json +383 -8
 - data/apis/source/redshift-2012-12-01.json +187 -60
 - data/apis/source/s3-2006-03-01.json +372 -21
 - data/apis/source/sns-2010-03-31.json +83 -36
 - data/features/s3/objects.feature +10 -0
 - data/features/s3/step_definitions.rb +33 -1
 - data/features/step_definitions.rb +2 -1
 - data/lib/aws.rb +3 -0
 - data/lib/aws/api/service_translators/ec2.rb +11 -0
 - data/lib/aws/api/service_translators/s3.rb +1 -0
 - data/lib/aws/credential_provider_chain.rb +1 -2
 - data/lib/aws/error_handler.rb +2 -1
 - data/lib/aws/plugins/ec2_copy_encrypted_snapshot.rb +86 -0
 - data/lib/aws/plugins/s3_md5s.rb +11 -8
 - data/lib/aws/plugins/s3_sse_cpk.rb +42 -0
 - data/lib/aws/query/builder.rb +4 -0
 - data/lib/aws/query/param.rb +1 -1
 - data/lib/aws/signers/base.rb +2 -0
 - data/lib/aws/signers/s3.rb +0 -1
 - data/lib/aws/signers/v4.rb +73 -22
 - data/lib/aws/version.rb +1 -1
 - data/spec/aws/operations_spec.rb +19 -15
 - data/spec/aws/plugins/s3_md5s_spec.rb +84 -0
 - data/spec/aws/query/builder_spec.rb +40 -0
 - data/spec/aws/query/param_spec.rb +5 -0
 - data/spec/aws/s3_spec.rb +27 -0
 - data/spec/aws/signers/v4_spec.rb +1 -1
 - data/spec/fixtures/operations/s3/412_response_head.yml +10 -0
 - data/spec/spec_helper.rb +7 -0
 - data/vendor/seahorse/lib/seahorse/client/handler_list.rb +3 -2
 - data/vendor/seahorse/lib/seahorse/client/http/headers.rb +4 -0
 - data/vendor/seahorse/lib/seahorse/client/net_http/handler.rb +1 -0
 - data/vendor/seahorse/lib/seahorse/client/plugins/operation_methods.rb +4 -2
 - data/vendor/seahorse/spec/seahorse/client/handler_list_spec.rb +2 -13
 - metadata +15 -2
 
    
        data/lib/aws/error_handler.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Aws
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                # This plugin auto populates the following request params for the
         
     | 
| 
      
 5 
     | 
    
         
            +
                # CopySnapshot API:
         
     | 
| 
      
 6 
     | 
    
         
            +
                #
         
     | 
| 
      
 7 
     | 
    
         
            +
                # * `:destination_region`
         
     | 
| 
      
 8 
     | 
    
         
            +
                # * `:presigned_url`
         
     | 
| 
      
 9 
     | 
    
         
            +
                #
         
     | 
| 
      
 10 
     | 
    
         
            +
                # These params are required by EC2 when copying an encrypted snapshot.
         
     | 
| 
      
 11 
     | 
    
         
            +
                class EC2CopyEncryptedSnapshot < Seahorse::Client::Plugin
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 14 
     | 
    
         
            +
                  class Handler < Seahorse::Client::Handler
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def call(context)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      params = context.params
         
     | 
| 
      
 18 
     | 
    
         
            +
                      unless params.key?(:destination_region)
         
     | 
| 
      
 19 
     | 
    
         
            +
                        params[:destination_region] = context.config.region
         
     | 
| 
      
 20 
     | 
    
         
            +
                        params[:presigned_url] = presigned_url(context.client, params)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @handler.call(context)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    private
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    def presigned_url(client, params)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      client = source_region_client(client, params)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      client.handle(PresignHandler, step: :build, priority: 0)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      client.copy_snapshot(params).data # presigned url
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    def source_region_client(client, params)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      config = client.config.to_h
         
     | 
| 
      
 35 
     | 
    
         
            +
                      config.delete(:endpoint)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      config[:region] = params[:source_region]
         
     | 
| 
      
 37 
     | 
    
         
            +
                      client.class.new(config)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  # This handler intentionally does NOT call the next handler in
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # the stack.  It generates a presigned url from the request
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # and returns it as the response data.
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # Before signing:
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # * The HTTP method is changed from POST to GET
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # * The url-encoded body is moved to the querystring
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 52 
     | 
    
         
            +
                  class PresignHandler < Seahorse::Client::Handler
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    def call(context)
         
     | 
| 
      
 55 
     | 
    
         
            +
                      convert_post_2_get(context)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      Seahorse::Client::Response.new(
         
     | 
| 
      
 57 
     | 
    
         
            +
                        context: context,
         
     | 
| 
      
 58 
     | 
    
         
            +
                        data: presigned_url(context.http_request, context.config))
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    private
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    def convert_post_2_get(context)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      context.http_request.http_method = 'GET'
         
     | 
| 
      
 65 
     | 
    
         
            +
                      context.http_request.endpoint = new_endpoint(context)
         
     | 
| 
      
 66 
     | 
    
         
            +
                      context.http_request.body = ''
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    def new_endpoint(context)
         
     | 
| 
      
 70 
     | 
    
         
            +
                      body = context.http_request.body_contents
         
     | 
| 
      
 71 
     | 
    
         
            +
                      endpoint = context.http_request.endpoint.to_s + '?' + body
         
     | 
| 
      
 72 
     | 
    
         
            +
                      Seahorse::Client::Http::Endpoint.new(endpoint)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    def presigned_url(http_request, config)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      signer = Signers::V4.new('ec2', config.credentials, config.region)
         
     | 
| 
      
 77 
     | 
    
         
            +
                      signer.presigned_url(http_request, expires_in: 3600)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  handler(Handler, step: :initialize, operations: [:copy_snapshot])
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/aws/plugins/s3_md5s.rb
    CHANGED
    
    | 
         @@ -1,13 +1,14 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
      
 1 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'base64'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            module Aws
         
     | 
| 
       5 
5 
     | 
    
         
             
              module Plugins
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                # @seahorse.client.option [Boolean] :compute_checksums (true)
         
     | 
| 
       8 
     | 
    
         
            -
                #   When `true` a MD5 checksum will be computed for  
     | 
| 
       9 
     | 
    
         
            -
                #    
     | 
| 
       10 
     | 
    
         
            -
                #    
     | 
| 
      
 8 
     | 
    
         
            +
                #   When `true` a MD5 checksum will be computed for every request that
         
     | 
| 
      
 9 
     | 
    
         
            +
                #   sends a body.  When `false`, MD5 checksums will only be computed
         
     | 
| 
      
 10 
     | 
    
         
            +
                #   for operations that require them.  Checksum errors returned by Amazon
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   S3 are automatically retried up to `:retry_limit` times.
         
     | 
| 
       11 
12 
     | 
    
         
             
                class S3Md5s < Seahorse::Client::Plugin
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
14 
     | 
    
         
             
                  # Amazon S3 requires these operations to have an MD5 checksum
         
     | 
| 
         @@ -25,13 +26,15 @@ module Aws 
     | 
|
| 
       25 
26 
     | 
    
         
             
                    OneMB = 1024 * 1024
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
                    def call(context)
         
     | 
| 
       28 
     | 
    
         
            -
                      context.http_request. 
     | 
| 
      
 29 
     | 
    
         
            +
                      body = context.http_request.body
         
     | 
| 
      
 30 
     | 
    
         
            +
                      if body.size > 0
         
     | 
| 
      
 31 
     | 
    
         
            +
                        context.http_request.headers['Content-Md5'] ||= md5(body)
         
     | 
| 
      
 32 
     | 
    
         
            +
                      end
         
     | 
| 
       29 
33 
     | 
    
         
             
                      @handler.call(context)
         
     | 
| 
       30 
34 
     | 
    
         
             
                    end
         
     | 
| 
       31 
35 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                    def md5( 
     | 
| 
       33 
     | 
    
         
            -
                      md5 = Digest::MD5.new
         
     | 
| 
       34 
     | 
    
         
            -
                      body = context.http_request.body
         
     | 
| 
      
 36 
     | 
    
         
            +
                    def md5(body)
         
     | 
| 
      
 37 
     | 
    
         
            +
                      md5 = OpenSSL::Digest::MD5.new
         
     | 
| 
       35 
38 
     | 
    
         
             
                      while chunk = body.read(OneMB)
         
     | 
| 
       36 
39 
     | 
    
         
             
                        md5.update(chunk)
         
     | 
| 
       37 
40 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'base64'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Aws
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 6 
     | 
    
         
            +
                class S3SseCpk < Seahorse::Client::Plugin
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  class Handler < Seahorse::Client::Handler
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def call(context)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      compute_key_md5(context.params)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      @handler.call(context)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    private
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    def compute_key_md5(params)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      if key = params[:sse_customer_key]
         
     | 
| 
      
 19 
     | 
    
         
            +
                        params[:sse_customer_key] = base64(key)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        params[:sse_customer_key_md5] = base64(md5(key))
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                      if key = params[:copy_source_sse_customer_key]
         
     | 
| 
      
 23 
     | 
    
         
            +
                        params[:copy_source_sse_customer_key] = base64(key)
         
     | 
| 
      
 24 
     | 
    
         
            +
                        params[:copy_source_sse_customer_key_md5] = base64(md5(key))
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    def md5(str)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      OpenSSL::Digest::MD5.digest(str)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    def base64(str)
         
     | 
| 
      
 33 
     | 
    
         
            +
                      Base64.encode64(str).strip
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  handler(Handler, step: :initialize)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/aws/query/builder.rb
    CHANGED
    
    
    
        data/lib/aws/query/param.rb
    CHANGED
    
    
    
        data/lib/aws/signers/base.rb
    CHANGED
    
    
    
        data/lib/aws/signers/s3.rb
    CHANGED
    
    
    
        data/lib/aws/signers/v4.rb
    CHANGED
    
    | 
         @@ -1,5 +1,4 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'time'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'digest/sha1'
         
     | 
| 
       3 
2 
     | 
    
         
             
            require 'openssl'
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            module Aws
         
     | 
| 
         @@ -8,8 +7,8 @@ module Aws 
     | 
|
| 
       8 
7 
     | 
    
         | 
| 
       9 
8 
     | 
    
         
             
                  def self.sign(context)
         
     | 
| 
       10 
9 
     | 
    
         
             
                    new(
         
     | 
| 
       11 
     | 
    
         
            -
                      context.config.credentials,
         
     | 
| 
       12 
10 
     | 
    
         
             
                      context.config.sigv4_name,
         
     | 
| 
      
 11 
     | 
    
         
            +
                      context.config.credentials,
         
     | 
| 
       13 
12 
     | 
    
         
             
                      context.config.sigv4_region
         
     | 
| 
       14 
13 
     | 
    
         
             
                    ).sign(context.http_request)
         
     | 
| 
       15 
14 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -20,48 +19,94 @@ module Aws 
     | 
|
| 
       20 
19 
     | 
    
         
             
                  #   the endpoint prefix.
         
     | 
| 
       21 
20 
     | 
    
         
             
                  # @param [String] region The region (e.g. 'us-west-1') the request
         
     | 
| 
       22 
21 
     | 
    
         
             
                  #   will be made to.
         
     | 
| 
       23 
     | 
    
         
            -
                  def initialize( 
     | 
| 
       24 
     | 
    
         
            -
                    @credentials = credentials
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def initialize(service_name, credentials, region)
         
     | 
| 
       25 
23 
     | 
    
         
             
                    @service_name = service_name
         
     | 
| 
      
 24 
     | 
    
         
            +
                    @credentials = credentials
         
     | 
| 
       26 
25 
     | 
    
         
             
                    @region = region
         
     | 
| 
       27 
26 
     | 
    
         
             
                  end
         
     | 
| 
       28 
27 
     | 
    
         | 
| 
       29 
28 
     | 
    
         
             
                  # @param [Seahorse::Client::Http::Request] request
         
     | 
| 
       30 
29 
     | 
    
         
             
                  # @return [Seahorse::Client::Http::Request] the signed request.
         
     | 
| 
       31 
     | 
    
         
            -
                  def sign( 
     | 
| 
      
 30 
     | 
    
         
            +
                  def sign(req)
         
     | 
| 
       32 
31 
     | 
    
         
             
                    datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
         
     | 
| 
       33 
     | 
    
         
            -
                     
     | 
| 
       34 
     | 
    
         
            -
                     
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
      
 32 
     | 
    
         
            +
                    body_digest = req.headers['X-Amz-Content-Sha256'] || hexdigest(req.body)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    req.headers['X-Amz-Date'] = datetime
         
     | 
| 
      
 34 
     | 
    
         
            +
                    req.headers['Host'] = req.endpoint.host
         
     | 
| 
      
 35 
     | 
    
         
            +
                    req.headers['X-Amz-Security-Token'] = credentials.session_token if
         
     | 
| 
       36 
36 
     | 
    
         
             
                      credentials.session_token
         
     | 
| 
       37 
     | 
    
         
            -
                     
     | 
| 
       38 
     | 
    
         
            -
                     
     | 
| 
       39 
     | 
    
         
            -
                     
     | 
| 
      
 37 
     | 
    
         
            +
                    req.headers['X-Amz-Content-Sha256'] ||= body_digest
         
     | 
| 
      
 38 
     | 
    
         
            +
                    req.headers['Authorization'] = authorization(req, datetime, body_digest)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    req
         
     | 
| 
       40 
40 
     | 
    
         
             
                  end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
      
 42 
     | 
    
         
            +
                  # Generates an returns a presigned URL.
         
     | 
| 
      
 43 
     | 
    
         
            +
                  # @param [Seahorse::Client::Http::Request] request
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # @option options [required, Integer<Seconds>] :expires_in
         
     | 
| 
      
 45 
     | 
    
         
            +
                  # @option options [optional, String] :body_digest The SHA256 hexdigest of
         
     | 
| 
      
 46 
     | 
    
         
            +
                  #   the payload to sign.  For S3, this should be the string literal
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #   `UNSIGNED-PALOAD`.
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @return [Seahorse::Client::Http::Request] the signed request.
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def presigned_url(request, options = {})
         
     | 
| 
      
 51 
     | 
    
         
            +
                    now = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
         
     | 
| 
      
 52 
     | 
    
         
            +
                    body_digest = options[:body_digest] || hexdigest(request.body)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    params = Query::ParamList.new
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    request.headers['Host'] ||= request.endpoint.host
         
     | 
| 
      
 57 
     | 
    
         
            +
                    request.headers.each do |header_name, header_value|
         
     | 
| 
      
 58 
     | 
    
         
            +
                      if header_name.match(/^x-amz/)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        params.set(header_name, header_value)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      unless %w(host content-md5).include?(header_name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                        request.headers.delete(header_name)
         
     | 
| 
      
 63 
     | 
    
         
            +
                      end
         
     | 
| 
      
 64 
     | 
    
         
            +
                    end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    params.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256")
         
     | 
| 
      
 67 
     | 
    
         
            +
                    params.set("X-Amz-Date", now)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    params.set("X-Amz-SignedHeaders", signed_headers(request))
         
     | 
| 
      
 69 
     | 
    
         
            +
                    params.set("X-Amz-Expires", options[:expires_in].to_s)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    params.set('X-Amz-Security-Token', credentials.session_token) if
         
     | 
| 
      
 71 
     | 
    
         
            +
                      credentials.session_token
         
     | 
| 
      
 72 
     | 
    
         
            +
                    params.set("X-Amz-Credential", credential(now))
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    endpoint = request.endpoint
         
     | 
| 
      
 75 
     | 
    
         
            +
                    if endpoint.querystring
         
     | 
| 
      
 76 
     | 
    
         
            +
                      endpoint.request_uri += '&' + params.to_s
         
     | 
| 
      
 77 
     | 
    
         
            +
                    else
         
     | 
| 
      
 78 
     | 
    
         
            +
                      endpoint.request_uri += '?' + params.to_s
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                    endpoint.to_s + '&X-Amz-Signature=' + signature(request, now, body_digest)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def authorization(request, datetime, body_digest)
         
     | 
| 
       43 
84 
     | 
    
         
             
                    parts = []
         
     | 
| 
       44 
     | 
    
         
            -
                    parts << "AWS4-HMAC-SHA256 Credential=#{ 
     | 
| 
      
 85 
     | 
    
         
            +
                    parts << "AWS4-HMAC-SHA256 Credential=#{credential(datetime)}"
         
     | 
| 
       45 
86 
     | 
    
         
             
                    parts << "SignedHeaders=#{signed_headers(request)}"
         
     | 
| 
       46 
     | 
    
         
            -
                    parts << "Signature=#{signature(request, datetime)}"
         
     | 
| 
      
 87 
     | 
    
         
            +
                    parts << "Signature=#{signature(request, datetime, body_digest)}"
         
     | 
| 
       47 
88 
     | 
    
         
             
                    parts.join(', ')
         
     | 
| 
       48 
89 
     | 
    
         
             
                  end
         
     | 
| 
       49 
90 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                  def  
     | 
| 
      
 91 
     | 
    
         
            +
                  def credential(datetime)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    "#{credentials.access_key_id}/#{credential_scope(datetime)}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  def signature(request, datetime, body_digest)
         
     | 
| 
       51 
96 
     | 
    
         
             
                    k_secret = credentials.secret_access_key
         
     | 
| 
       52 
97 
     | 
    
         
             
                    k_date = hmac("AWS4" + k_secret, datetime[0,8])
         
     | 
| 
       53 
98 
     | 
    
         
             
                    k_region = hmac(k_date, region)
         
     | 
| 
       54 
99 
     | 
    
         
             
                    k_service = hmac(k_region, service_name)
         
     | 
| 
       55 
100 
     | 
    
         
             
                    k_credentials = hmac(k_service, 'aws4_request')
         
     | 
| 
       56 
     | 
    
         
            -
                    hexhmac(k_credentials, string_to_sign(request, datetime))
         
     | 
| 
      
 101 
     | 
    
         
            +
                    hexhmac(k_credentials, string_to_sign(request, datetime, body_digest))
         
     | 
| 
       57 
102 
     | 
    
         
             
                  end
         
     | 
| 
       58 
103 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                  def string_to_sign(request, datetime)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  def string_to_sign(request, datetime, body_digest)
         
     | 
| 
       60 
105 
     | 
    
         
             
                    parts = []
         
     | 
| 
       61 
106 
     | 
    
         
             
                    parts << 'AWS4-HMAC-SHA256'
         
     | 
| 
       62 
107 
     | 
    
         
             
                    parts << datetime
         
     | 
| 
       63 
108 
     | 
    
         
             
                    parts << credential_scope(datetime)
         
     | 
| 
       64 
     | 
    
         
            -
                    parts << hexdigest(canonical_request(request))
         
     | 
| 
      
 109 
     | 
    
         
            +
                    parts << hexdigest(canonical_request(request, body_digest))
         
     | 
| 
       65 
110 
     | 
    
         
             
                    parts.join("\n")
         
     | 
| 
       66 
111 
     | 
    
         
             
                  end
         
     | 
| 
       67 
112 
     | 
    
         | 
| 
         @@ -74,17 +119,23 @@ module Aws 
     | 
|
| 
       74 
119 
     | 
    
         
             
                    parts.join("/")
         
     | 
| 
       75 
120 
     | 
    
         
             
                  end
         
     | 
| 
       76 
121 
     | 
    
         | 
| 
       77 
     | 
    
         
            -
                  def canonical_request(request)
         
     | 
| 
      
 122 
     | 
    
         
            +
                  def canonical_request(request, body_digest)
         
     | 
| 
       78 
123 
     | 
    
         
             
                    [
         
     | 
| 
       79 
124 
     | 
    
         
             
                      request.http_method,
         
     | 
| 
       80 
125 
     | 
    
         
             
                      request.endpoint.path,
         
     | 
| 
       81 
     | 
    
         
            -
                      request.endpoint.querystring,
         
     | 
| 
      
 126 
     | 
    
         
            +
                      normalized_querystring(request.endpoint.querystring),
         
     | 
| 
       82 
127 
     | 
    
         
             
                      canonical_headers(request) + "\n",
         
     | 
| 
       83 
128 
     | 
    
         
             
                      signed_headers(request),
         
     | 
| 
       84 
     | 
    
         
            -
                       
     | 
| 
      
 129 
     | 
    
         
            +
                      body_digest
         
     | 
| 
       85 
130 
     | 
    
         
             
                    ].join("\n")
         
     | 
| 
       86 
131 
     | 
    
         
             
                  end
         
     | 
| 
       87 
132 
     | 
    
         | 
| 
      
 133 
     | 
    
         
            +
                  def normalized_querystring(querystring)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    if querystring
         
     | 
| 
      
 135 
     | 
    
         
            +
                      querystring.split('&').sort.join('&')
         
     | 
| 
      
 136 
     | 
    
         
            +
                    end
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       88 
139 
     | 
    
         
             
                  def signed_headers(request)
         
     | 
| 
       89 
140 
     | 
    
         
             
                    headers = request.headers.keys
         
     | 
| 
       90 
141 
     | 
    
         
             
                    headers.delete('authorization')
         
     | 
| 
         @@ -106,7 +157,7 @@ module Aws 
     | 
|
| 
       106 
157 
     | 
    
         
             
                  end
         
     | 
| 
       107 
158 
     | 
    
         | 
| 
       108 
159 
     | 
    
         
             
                  def hexdigest(value)
         
     | 
| 
       109 
     | 
    
         
            -
                    digest = Digest::SHA256.new
         
     | 
| 
      
 160 
     | 
    
         
            +
                    digest = OpenSSL::Digest::SHA256.new
         
     | 
| 
       110 
161 
     | 
    
         
             
                    if value.respond_to?(:read)
         
     | 
| 
       111 
162 
     | 
    
         
             
                      chunk = nil
         
     | 
| 
       112 
163 
     | 
    
         
             
                      chunk_size = 1024 * 1024 # 1 megabyte
         
     | 
    
        data/lib/aws/version.rb
    CHANGED
    
    
    
        data/spec/aws/operations_spec.rb
    CHANGED
    
    | 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'stringio'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Aws
         
     | 
| 
       4 
5 
     | 
    
         
             
              describe 'Aws' do
         
     | 
| 
         @@ -116,27 +117,30 @@ module Aws 
     | 
|
| 
       116 
117 
     | 
    
         
             
                      fixture_name = path.split('/')[-1][0..-5]
         
     | 
| 
       117 
118 
     | 
    
         | 
| 
       118 
119 
     | 
    
         
             
                      it(fixture_name) do
         
     | 
| 
       119 
     | 
    
         
            -
                         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
      
 120 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 121 
     | 
    
         
            +
                          # load the fixture from disk
         
     | 
| 
      
 122 
     | 
    
         
            +
                          f = OperationFixture.load(svc_name, fixture_name)
         
     | 
| 
       121 
123 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
      
 124 
     | 
    
         
            +
                          # remove the plugin that raises errors
         
     | 
| 
      
 125 
     | 
    
         
            +
                          Aws.service_classes[svc_name.to_sym].remove_plugin(
         
     | 
| 
      
 126 
     | 
    
         
            +
                            Seahorse::Client::Plugins::RaiseResponseErrors)
         
     | 
| 
       125 
127 
     | 
    
         | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
      
 128 
     | 
    
         
            +
                          # build the service interface
         
     | 
| 
      
 129 
     | 
    
         
            +
                          svc = Aws.send(svc_name, f.config)
         
     | 
| 
       128 
130 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
      
 131 
     | 
    
         
            +
                          # build the request
         
     | 
| 
      
 132 
     | 
    
         
            +
                          req = svc.build_request(f.operation, f.params)
         
     | 
| 
      
 133 
     | 
    
         
            +
                          req.handler(f.handler, step: :send)
         
     | 
| 
       132 
134 
     | 
    
         | 
| 
       133 
135 
     | 
    
         | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
                        request_assertions(f, resp.context.http_request)
         
     | 
| 
       138 
     | 
    
         
            -
                        response_assertions(f, resp)
         
     | 
| 
      
 136 
     | 
    
         
            +
                          # send the request
         
     | 
| 
      
 137 
     | 
    
         
            +
                          resp = req.send_request
         
     | 
| 
       139 
138 
     | 
    
         | 
| 
      
 139 
     | 
    
         
            +
                          request_assertions(f, resp.context.http_request)
         
     | 
| 
      
 140 
     | 
    
         
            +
                          response_assertions(f, resp)
         
     | 
| 
      
 141 
     | 
    
         
            +
                        ensure
         
     | 
| 
      
 142 
     | 
    
         
            +
                          Aws.service_classes[svc_name.to_sym].add_plugin(Seahorse::Client::Plugins::RaiseResponseErrors)
         
     | 
| 
      
 143 
     | 
    
         
            +
                        end
         
     | 
| 
       140 
144 
     | 
    
         
             
                      end
         
     | 
| 
       141 
145 
     | 
    
         
             
                    end
         
     | 
| 
       142 
146 
     | 
    
         
             
                  end
         
     |