aws-sdk-resources 2.11.361 → 3.49.0
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/bin/aws-v3.rb +192 -0
 - data/lib/aws-sdk-resources.rb +189 -87
 - metadata +2594 -69
 - data/lib/aws-sdk-resources/batch.rb +0 -143
 - data/lib/aws-sdk-resources/builder.rb +0 -85
 - data/lib/aws-sdk-resources/builder_sources.rb +0 -105
 - data/lib/aws-sdk-resources/collection.rb +0 -107
 - data/lib/aws-sdk-resources/definition.rb +0 -331
 - data/lib/aws-sdk-resources/documenter.rb +0 -70
 - data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +0 -279
 - data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +0 -25
 - data/lib/aws-sdk-resources/documenter/has_many_operation_documenter.rb +0 -69
 - data/lib/aws-sdk-resources/documenter/has_operation_documenter.rb +0 -66
 - data/lib/aws-sdk-resources/documenter/operation_documenter.rb +0 -20
 - data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +0 -53
 - data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +0 -77
 - data/lib/aws-sdk-resources/errors.rb +0 -15
 - data/lib/aws-sdk-resources/operation_methods.rb +0 -83
 - data/lib/aws-sdk-resources/operations.rb +0 -280
 - data/lib/aws-sdk-resources/options.rb +0 -17
 - data/lib/aws-sdk-resources/request.rb +0 -39
 - data/lib/aws-sdk-resources/request_params.rb +0 -140
 - data/lib/aws-sdk-resources/resource.rb +0 -243
 - data/lib/aws-sdk-resources/services/ec2.rb +0 -21
 - data/lib/aws-sdk-resources/services/ec2/instance.rb +0 -29
 - data/lib/aws-sdk-resources/services/iam.rb +0 -19
 - data/lib/aws-sdk-resources/services/s3.rb +0 -20
 - data/lib/aws-sdk-resources/services/s3/bucket.rb +0 -127
 - data/lib/aws-sdk-resources/services/s3/encryption.rb +0 -21
 - data/lib/aws-sdk-resources/services/s3/encryption/client.rb +0 -369
 - data/lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb +0 -174
 - data/lib/aws-sdk-resources/services/s3/encryption/default_cipher_provider.rb +0 -63
 - data/lib/aws-sdk-resources/services/s3/encryption/default_key_provider.rb +0 -38
 - data/lib/aws-sdk-resources/services/s3/encryption/encrypt_handler.rb +0 -50
 - data/lib/aws-sdk-resources/services/s3/encryption/errors.rb +0 -13
 - data/lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb +0 -56
 - data/lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb +0 -29
 - data/lib/aws-sdk-resources/services/s3/encryption/io_encrypter.rb +0 -69
 - data/lib/aws-sdk-resources/services/s3/encryption/key_provider.rb +0 -29
 - data/lib/aws-sdk-resources/services/s3/encryption/kms_cipher_provider.rb +0 -71
 - data/lib/aws-sdk-resources/services/s3/encryption/materials.rb +0 -58
 - data/lib/aws-sdk-resources/services/s3/encryption/utils.rb +0 -79
 - data/lib/aws-sdk-resources/services/s3/file_downloader.rb +0 -169
 - data/lib/aws-sdk-resources/services/s3/file_part.rb +0 -75
 - data/lib/aws-sdk-resources/services/s3/file_uploader.rb +0 -58
 - data/lib/aws-sdk-resources/services/s3/multipart_file_uploader.rb +0 -187
 - data/lib/aws-sdk-resources/services/s3/multipart_upload.rb +0 -42
 - data/lib/aws-sdk-resources/services/s3/multipart_upload_error.rb +0 -16
 - data/lib/aws-sdk-resources/services/s3/object.rb +0 -290
 - data/lib/aws-sdk-resources/services/s3/object_copier.rb +0 -99
 - data/lib/aws-sdk-resources/services/s3/object_multipart_copier.rb +0 -180
 - data/lib/aws-sdk-resources/services/s3/object_summary.rb +0 -73
 - data/lib/aws-sdk-resources/services/s3/presigned_post.rb +0 -647
 - data/lib/aws-sdk-resources/services/sns.rb +0 -7
 - data/lib/aws-sdk-resources/services/sns/message_verifier.rb +0 -171
 - data/lib/aws-sdk-resources/services/sqs.rb +0 -7
 - data/lib/aws-sdk-resources/services/sqs/queue_poller.rb +0 -521
 - data/lib/aws-sdk-resources/source.rb +0 -39
 
| 
         @@ -1,29 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module Aws
         
     | 
| 
       2 
     | 
    
         
            -
              module S3
         
     | 
| 
       3 
     | 
    
         
            -
                module Encryption
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                  # This module defines the interface required for a {Client#key_provider}.
         
     | 
| 
       6 
     | 
    
         
            -
                  # A key provider is any object that:
         
     | 
| 
       7 
     | 
    
         
            -
                  #
         
     | 
| 
       8 
     | 
    
         
            -
                  # * Responds to {#encryption_materials} with an {Materials} object.
         
     | 
| 
       9 
     | 
    
         
            -
                  #
         
     | 
| 
       10 
     | 
    
         
            -
                  # * Responds to {#key_for}, receiving a JSON document String,
         
     | 
| 
       11 
     | 
    
         
            -
                  #   returning an encryption key. The returned encryption key
         
     | 
| 
       12 
     | 
    
         
            -
                  #   must be one of:
         
     | 
| 
       13 
     | 
    
         
            -
                  #
         
     | 
| 
       14 
     | 
    
         
            -
                  #   * `OpenSSL::PKey::RSA` - for asymmetric encryption
         
     | 
| 
       15 
     | 
    
         
            -
                  #   * `String` - 32, 24, or 16 bytes long, for symmetric encryption
         
     | 
| 
       16 
     | 
    
         
            -
                  #
         
     | 
| 
       17 
     | 
    
         
            -
                  module KeyProvider
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                    # @return [Materials]
         
     | 
| 
       20 
     | 
    
         
            -
                    def encryption_materials; end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                    # @param [String<JSON>] materials_description
         
     | 
| 
       23 
     | 
    
         
            -
                    # @return [OpenSSL::PKey::RSA, String] encryption_key
         
     | 
| 
       24 
     | 
    
         
            -
                    def key_for(materials_description); end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  end
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
              end
         
     | 
| 
       29 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,71 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'base64'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module Aws
         
     | 
| 
       4 
     | 
    
         
            -
              module S3
         
     | 
| 
       5 
     | 
    
         
            -
                module Encryption
         
     | 
| 
       6 
     | 
    
         
            -
                  # @api private
         
     | 
| 
       7 
     | 
    
         
            -
                  class KmsCipherProvider
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                    def initialize(options = {})
         
     | 
| 
       10 
     | 
    
         
            -
                      @kms_key_id = options[:kms_key_id]
         
     | 
| 
       11 
     | 
    
         
            -
                      @kms_client = options[:kms_client]
         
     | 
| 
       12 
     | 
    
         
            -
                    end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    # @return [Array<Hash,Cipher>] Creates an returns a new encryption
         
     | 
| 
       15 
     | 
    
         
            -
                    #   envelope and encryption cipher.
         
     | 
| 
       16 
     | 
    
         
            -
                    def encryption_cipher
         
     | 
| 
       17 
     | 
    
         
            -
                      encryption_context = { "kms_cmk_id" => @kms_key_id }
         
     | 
| 
       18 
     | 
    
         
            -
                      key_data = @kms_client.generate_data_key(
         
     | 
| 
       19 
     | 
    
         
            -
                        key_id: @kms_key_id,
         
     | 
| 
       20 
     | 
    
         
            -
                        encryption_context: encryption_context,
         
     | 
| 
       21 
     | 
    
         
            -
                        key_spec: 'AES_256',
         
     | 
| 
       22 
     | 
    
         
            -
                      )
         
     | 
| 
       23 
     | 
    
         
            -
                      cipher = Utils.aes_encryption_cipher(:CBC)
         
     | 
| 
       24 
     | 
    
         
            -
                      cipher.key = key_data.plaintext
         
     | 
| 
       25 
     | 
    
         
            -
                      envelope = {
         
     | 
| 
       26 
     | 
    
         
            -
                        'x-amz-key-v2' => encode64(key_data.ciphertext_blob),
         
     | 
| 
       27 
     | 
    
         
            -
                        'x-amz-iv' => encode64(cipher.iv = cipher.random_iv),
         
     | 
| 
       28 
     | 
    
         
            -
                        'x-amz-cek-alg' => 'AES/CBC/PKCS5Padding',
         
     | 
| 
       29 
     | 
    
         
            -
                        'x-amz-wrap-alg' => 'kms',
         
     | 
| 
       30 
     | 
    
         
            -
                        'x-amz-matdesc' => Json.dump(encryption_context)
         
     | 
| 
       31 
     | 
    
         
            -
                      }
         
     | 
| 
       32 
     | 
    
         
            -
                      [envelope, cipher]
         
     | 
| 
       33 
     | 
    
         
            -
                    end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                    # @return [Cipher] Given an encryption envelope, returns a
         
     | 
| 
       36 
     | 
    
         
            -
                    #   decryption cipher.
         
     | 
| 
       37 
     | 
    
         
            -
                    def decryption_cipher(envelope)
         
     | 
| 
       38 
     | 
    
         
            -
                      encryption_context = Json.load(envelope['x-amz-matdesc'])
         
     | 
| 
       39 
     | 
    
         
            -
                      key = @kms_client.decrypt(
         
     | 
| 
       40 
     | 
    
         
            -
                        ciphertext_blob: decode64(envelope['x-amz-key-v2']),
         
     | 
| 
       41 
     | 
    
         
            -
                        encryption_context: encryption_context,
         
     | 
| 
       42 
     | 
    
         
            -
                      ).plaintext
         
     | 
| 
       43 
     | 
    
         
            -
                      iv = decode64(envelope['x-amz-iv'])
         
     | 
| 
       44 
     | 
    
         
            -
                      block_mode =
         
     | 
| 
       45 
     | 
    
         
            -
                        case envelope['x-amz-cek-alg']
         
     | 
| 
       46 
     | 
    
         
            -
                        when 'AES/CBC/PKCS5Padding'
         
     | 
| 
       47 
     | 
    
         
            -
                          :CBC
         
     | 
| 
       48 
     | 
    
         
            -
                        when 'AES/GCM/NoPadding'
         
     | 
| 
       49 
     | 
    
         
            -
                          :GCM
         
     | 
| 
       50 
     | 
    
         
            -
                        else
         
     | 
| 
       51 
     | 
    
         
            -
                          type = envelope['x-amz-cek-alg'].inspect
         
     | 
| 
       52 
     | 
    
         
            -
                          msg = "unsupported content encrypting key (cek) format: #{type}"
         
     | 
| 
       53 
     | 
    
         
            -
                          raise Errors::DecryptionError, msg
         
     | 
| 
       54 
     | 
    
         
            -
                        end
         
     | 
| 
       55 
     | 
    
         
            -
                      Utils.aes_decryption_cipher(block_mode, key, iv)
         
     | 
| 
       56 
     | 
    
         
            -
                    end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    private
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    def encode64(str)
         
     | 
| 
       61 
     | 
    
         
            -
                      Base64.encode64(str).split("\n") * ""
         
     | 
| 
       62 
     | 
    
         
            -
                    end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                    def decode64(str)
         
     | 
| 
       65 
     | 
    
         
            -
                      Base64.decode64(str)
         
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
       69 
     | 
    
         
            -
                end
         
     | 
| 
       70 
     | 
    
         
            -
              end
         
     | 
| 
       71 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,58 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'base64'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module Aws
         
     | 
| 
       4 
     | 
    
         
            -
              module S3
         
     | 
| 
       5 
     | 
    
         
            -
                module Encryption
         
     | 
| 
       6 
     | 
    
         
            -
                  class Materials
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                    # @option options [required, OpenSSL::PKey::RSA, String] :key
         
     | 
| 
       9 
     | 
    
         
            -
                    #   The master key to use for encrypting/decrypting all objects.
         
     | 
| 
       10 
     | 
    
         
            -
                    #
         
     | 
| 
       11 
     | 
    
         
            -
                    # @option options [String<JSON>] :description ('{}')
         
     | 
| 
       12 
     | 
    
         
            -
                    #   The encryption materials description. This is must be
         
     | 
| 
       13 
     | 
    
         
            -
                    #   a JSON document string.
         
     | 
| 
       14 
     | 
    
         
            -
                    #
         
     | 
| 
       15 
     | 
    
         
            -
                    def initialize(options = {})
         
     | 
| 
       16 
     | 
    
         
            -
                      @key = validate_key(options[:key])
         
     | 
| 
       17 
     | 
    
         
            -
                      @description = validate_desc(options[:description])
         
     | 
| 
       18 
     | 
    
         
            -
                    end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                    # @return [OpenSSL::PKey::RSA, String]
         
     | 
| 
       21 
     | 
    
         
            -
                    attr_reader :key
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                    # @return [String<JSON>]
         
     | 
| 
       24 
     | 
    
         
            -
                    attr_reader :description
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                    private
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                    def validate_key(key)
         
     | 
| 
       29 
     | 
    
         
            -
                      case key
         
     | 
| 
       30 
     | 
    
         
            -
                      when OpenSSL::PKey::RSA then key
         
     | 
| 
       31 
     | 
    
         
            -
                      when String
         
     | 
| 
       32 
     | 
    
         
            -
                        if [32, 24, 16].include?(key.bytesize)
         
     | 
| 
       33 
     | 
    
         
            -
                          key
         
     | 
| 
       34 
     | 
    
         
            -
                        else
         
     | 
| 
       35 
     | 
    
         
            -
                          msg = "invalid key, symmetric key required to be 16, 24, or "
         
     | 
| 
       36 
     | 
    
         
            -
                          msg << "32 bytes in length, saw length " + key.bytesize.to_s
         
     | 
| 
       37 
     | 
    
         
            -
                          raise ArgumentError, msg
         
     | 
| 
       38 
     | 
    
         
            -
                        end
         
     | 
| 
       39 
     | 
    
         
            -
                      else
         
     | 
| 
       40 
     | 
    
         
            -
                        msg = "invalid encryption key, expected an OpenSSL::PKey::RSA key "
         
     | 
| 
       41 
     | 
    
         
            -
                        msg << "(for asymmetric encryption) or a String (for symmetric "
         
     | 
| 
       42 
     | 
    
         
            -
                        msg << "encryption)."
         
     | 
| 
       43 
     | 
    
         
            -
                        raise ArgumentError, msg
         
     | 
| 
       44 
     | 
    
         
            -
                      end
         
     | 
| 
       45 
     | 
    
         
            -
                    end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                    def validate_desc(description)
         
     | 
| 
       48 
     | 
    
         
            -
                      Json.load(description)
         
     | 
| 
       49 
     | 
    
         
            -
                      description
         
     | 
| 
       50 
     | 
    
         
            -
                    rescue Json::ParseError, EncodingError
         
     | 
| 
       51 
     | 
    
         
            -
                      msg = "expected description to be a valid JSON document string"
         
     | 
| 
       52 
     | 
    
         
            -
                      raise ArgumentError, msg
         
     | 
| 
       53 
     | 
    
         
            -
                    end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                  end
         
     | 
| 
       56 
     | 
    
         
            -
                end
         
     | 
| 
       57 
     | 
    
         
            -
              end
         
     | 
| 
       58 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,79 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'openssl'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module Aws
         
     | 
| 
       4 
     | 
    
         
            -
              module S3
         
     | 
| 
       5 
     | 
    
         
            -
                module Encryption
         
     | 
| 
       6 
     | 
    
         
            -
                  # @api private
         
     | 
| 
       7 
     | 
    
         
            -
                  module Utils
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                    UNSAFE_MSG = "unsafe encryption, data is longer than key length"
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                    class << self
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                      def encrypt(key, data)
         
     | 
| 
       14 
     | 
    
         
            -
                        case key
         
     | 
| 
       15 
     | 
    
         
            -
                        when OpenSSL::PKey::RSA # asymmetric encryption
         
     | 
| 
       16 
     | 
    
         
            -
                          warn(UNSAFE_MSG) if key.public_key.n.num_bits < cipher_size(data)
         
     | 
| 
       17 
     | 
    
         
            -
                          key.public_encrypt(data)
         
     | 
| 
       18 
     | 
    
         
            -
                        when String # symmetric encryption
         
     | 
| 
       19 
     | 
    
         
            -
                          warn(UNSAFE_MSG) if cipher_size(key) < cipher_size(data)
         
     | 
| 
       20 
     | 
    
         
            -
                          cipher = aes_encryption_cipher(:ECB, key)
         
     | 
| 
       21 
     | 
    
         
            -
                          cipher.update(data) + cipher.final
         
     | 
| 
       22 
     | 
    
         
            -
                        end
         
     | 
| 
       23 
     | 
    
         
            -
                      end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                      def decrypt(key, data)
         
     | 
| 
       26 
     | 
    
         
            -
                        begin
         
     | 
| 
       27 
     | 
    
         
            -
                          case key
         
     | 
| 
       28 
     | 
    
         
            -
                          when OpenSSL::PKey::RSA # asymmetric decryption
         
     | 
| 
       29 
     | 
    
         
            -
                            key.private_decrypt(data)
         
     | 
| 
       30 
     | 
    
         
            -
                          when String # symmetric Decryption
         
     | 
| 
       31 
     | 
    
         
            -
                            cipher = aes_cipher(:decrypt, :ECB, key, nil)
         
     | 
| 
       32 
     | 
    
         
            -
                            cipher.update(data) + cipher.final
         
     | 
| 
       33 
     | 
    
         
            -
                          end
         
     | 
| 
       34 
     | 
    
         
            -
                        rescue OpenSSL::Cipher::CipherError
         
     | 
| 
       35 
     | 
    
         
            -
                          msg = 'decryption failed, possible incorrect key'
         
     | 
| 
       36 
     | 
    
         
            -
                          raise Errors::DecryptionError, msg
         
     | 
| 
       37 
     | 
    
         
            -
                        end
         
     | 
| 
       38 
     | 
    
         
            -
                      end
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                      # @param [String] block_mode "CBC" or "ECB"
         
     | 
| 
       41 
     | 
    
         
            -
                      # @param [OpenSSL::PKey::RSA, String, nil] key
         
     | 
| 
       42 
     | 
    
         
            -
                      # @param [String, nil] iv The initialization vector
         
     | 
| 
       43 
     | 
    
         
            -
                      def aes_encryption_cipher(block_mode, key = nil, iv = nil)
         
     | 
| 
       44 
     | 
    
         
            -
                        aes_cipher(:encrypt, block_mode, key, iv)
         
     | 
| 
       45 
     | 
    
         
            -
                      end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                      # @param [String] block_mode "CBC" or "ECB"
         
     | 
| 
       48 
     | 
    
         
            -
                      # @param [OpenSSL::PKey::RSA, String, nil] key
         
     | 
| 
       49 
     | 
    
         
            -
                      # @param [String, nil] iv The initialization vector
         
     | 
| 
       50 
     | 
    
         
            -
                      def aes_decryption_cipher(block_mode, key = nil, iv = nil)
         
     | 
| 
       51 
     | 
    
         
            -
                        aes_cipher(:decrypt, block_mode, key, iv)
         
     | 
| 
       52 
     | 
    
         
            -
                      end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                      # @param [String] mode "encrypt" or "decrypt"
         
     | 
| 
       55 
     | 
    
         
            -
                      # @param [String] block_mode "CBC" or "ECB"
         
     | 
| 
       56 
     | 
    
         
            -
                      # @param [OpenSSL::PKey::RSA, String, nil] key
         
     | 
| 
       57 
     | 
    
         
            -
                      # @param [String, nil] iv The initialization vector
         
     | 
| 
       58 
     | 
    
         
            -
                      def aes_cipher(mode, block_mode, key, iv)
         
     | 
| 
       59 
     | 
    
         
            -
                        cipher = key ?
         
     | 
| 
       60 
     | 
    
         
            -
                          OpenSSL::Cipher.new("aes-#{cipher_size(key)}-#{block_mode.downcase}") :
         
     | 
| 
       61 
     | 
    
         
            -
                          OpenSSL::Cipher.new("aes-256-#{block_mode.downcase}")
         
     | 
| 
       62 
     | 
    
         
            -
                        cipher.send(mode) # encrypt or decrypt
         
     | 
| 
       63 
     | 
    
         
            -
                        cipher.key = key if key
         
     | 
| 
       64 
     | 
    
         
            -
                        cipher.iv = iv if iv
         
     | 
| 
       65 
     | 
    
         
            -
                        cipher
         
     | 
| 
       66 
     | 
    
         
            -
                      end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                      # @param [String] key
         
     | 
| 
       69 
     | 
    
         
            -
                      # @return [Integer]
         
     | 
| 
       70 
     | 
    
         
            -
                      # @raise ArgumentError
         
     | 
| 
       71 
     | 
    
         
            -
                      def cipher_size(key)
         
     | 
| 
       72 
     | 
    
         
            -
                        key.bytesize * 8
         
     | 
| 
       73 
     | 
    
         
            -
                      end
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                    end
         
     | 
| 
       76 
     | 
    
         
            -
                  end
         
     | 
| 
       77 
     | 
    
         
            -
                end
         
     | 
| 
       78 
     | 
    
         
            -
              end
         
     | 
| 
       79 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,169 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'thread'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'set'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'tmpdir'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            module Aws
         
     | 
| 
       7 
     | 
    
         
            -
              module S3
         
     | 
| 
       8 
     | 
    
         
            -
                # @api private
         
     | 
| 
       9 
     | 
    
         
            -
                class FileDownloader
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  MIN_CHUNK_SIZE = 5 * 1024 * 1024
         
     | 
| 
       12 
     | 
    
         
            -
                  MAX_PARTS = 10_000
         
     | 
| 
       13 
     | 
    
         
            -
                  THREAD_COUNT = 10
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  def initialize(options = {})
         
     | 
| 
       16 
     | 
    
         
            -
                    @client = options[:client] || Client.new
         
     | 
| 
       17 
     | 
    
         
            -
                  end
         
     | 
| 
       18 
     | 
    
         
            -
                  
         
     | 
| 
       19 
     | 
    
         
            -
                  # @return [Client]
         
     | 
| 
       20 
     | 
    
         
            -
                  attr_reader :client
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  def download(destination, options = {})
         
     | 
| 
       23 
     | 
    
         
            -
                    @path = destination
         
     | 
| 
       24 
     | 
    
         
            -
                    @mode = options[:mode] || "auto"
         
     | 
| 
       25 
     | 
    
         
            -
                    @thread_count = options[:thread_count] || THREAD_COUNT
         
     | 
| 
       26 
     | 
    
         
            -
                    @chunk_size = options[:chunk_size]
         
     | 
| 
       27 
     | 
    
         
            -
                    @bucket = options[:bucket]
         
     | 
| 
       28 
     | 
    
         
            -
                    @key = options[:key]
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                    case @mode
         
     | 
| 
       31 
     | 
    
         
            -
                    when "auto" then multipart_download
         
     | 
| 
       32 
     | 
    
         
            -
                    when "single_request" then single_request
         
     | 
| 
       33 
     | 
    
         
            -
                    when "get_range"
         
     | 
| 
       34 
     | 
    
         
            -
                      if @chunk_size
         
     | 
| 
       35 
     | 
    
         
            -
                        resp = @client.head_object(bucket: @bucket, key: @key)
         
     | 
| 
       36 
     | 
    
         
            -
                        multithreaded_get_by_ranges(construct_chunks(resp.content_length))
         
     | 
| 
       37 
     | 
    
         
            -
                      else
         
     | 
| 
       38 
     | 
    
         
            -
                        msg = "In :get_range mode, :chunk_size must be provided"
         
     | 
| 
       39 
     | 
    
         
            -
                        raise ArgumentError, msg
         
     | 
| 
       40 
     | 
    
         
            -
                      end
         
     | 
| 
       41 
     | 
    
         
            -
                    else
         
     | 
| 
       42 
     | 
    
         
            -
                      msg = "Invalid mode #{@mode} provided, "\
         
     | 
| 
       43 
     | 
    
         
            -
                        "mode should be :single_request, :get_range or :auto"
         
     | 
| 
       44 
     | 
    
         
            -
                      raise ArgumentError, msg
         
     | 
| 
       45 
     | 
    
         
            -
                    end
         
     | 
| 
       46 
     | 
    
         
            -
                  end
         
     | 
| 
       47 
     | 
    
         
            -
                  
         
     | 
| 
       48 
     | 
    
         
            -
                  private
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  def multipart_download
         
     | 
| 
       51 
     | 
    
         
            -
                    resp = @client.head_object(bucket: @bucket, key: @key, part_number: 1)
         
     | 
| 
       52 
     | 
    
         
            -
                    count = resp.parts_count
         
     | 
| 
       53 
     | 
    
         
            -
                    if count.nil? || count <= 1
         
     | 
| 
       54 
     | 
    
         
            -
                      resp.content_length < MIN_CHUNK_SIZE ?
         
     | 
| 
       55 
     | 
    
         
            -
                        single_request :
         
     | 
| 
       56 
     | 
    
         
            -
                        multithreaded_get_by_ranges(construct_chunks(resp.content_length))
         
     | 
| 
       57 
     | 
    
         
            -
                    else
         
     | 
| 
       58 
     | 
    
         
            -
                      # partNumber is an option
         
     | 
| 
       59 
     | 
    
         
            -
                      resp = @client.head_object(bucket: @bucket, key: @key)
         
     | 
| 
       60 
     | 
    
         
            -
                      resp.content_length < MIN_CHUNK_SIZE ?
         
     | 
| 
       61 
     | 
    
         
            -
                        single_request :
         
     | 
| 
       62 
     | 
    
         
            -
                        compute_mode(resp.content_length, count)
         
     | 
| 
       63 
     | 
    
         
            -
                    end
         
     | 
| 
       64 
     | 
    
         
            -
                  end
         
     | 
| 
       65 
     | 
    
         
            -
             
         
     | 
| 
       66 
     | 
    
         
            -
                  def compute_mode(file_size, count)
         
     | 
| 
       67 
     | 
    
         
            -
                    chunk_size = compute_chunk(file_size)
         
     | 
| 
       68 
     | 
    
         
            -
                    part_size = (file_size.to_f / count.to_f).ceil
         
     | 
| 
       69 
     | 
    
         
            -
                    if chunk_size < part_size
         
     | 
| 
       70 
     | 
    
         
            -
                      multithreaded_get_by_ranges(construct_chunks(file_size))
         
     | 
| 
       71 
     | 
    
         
            -
                    else
         
     | 
| 
       72 
     | 
    
         
            -
                      multithreaded_get_by_parts(count)
         
     | 
| 
       73 
     | 
    
         
            -
                    end
         
     | 
| 
       74 
     | 
    
         
            -
                  end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                  def construct_chunks(file_size)
         
     | 
| 
       77 
     | 
    
         
            -
                    offset = 0
         
     | 
| 
       78 
     | 
    
         
            -
                    default_chunk_size = compute_chunk(file_size)
         
     | 
| 
       79 
     | 
    
         
            -
                    chunks = []
         
     | 
| 
       80 
     | 
    
         
            -
                    while offset <= file_size
         
     | 
| 
       81 
     | 
    
         
            -
                      progress = offset + default_chunk_size
         
     | 
| 
       82 
     | 
    
         
            -
                      chunks << "bytes=#{offset}-#{progress < file_size ? progress : file_size}"
         
     | 
| 
       83 
     | 
    
         
            -
                      offset = progress + 1
         
     | 
| 
       84 
     | 
    
         
            -
                    end
         
     | 
| 
       85 
     | 
    
         
            -
                    chunks
         
     | 
| 
       86 
     | 
    
         
            -
                  end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                  def compute_chunk(file_size)
         
     | 
| 
       89 
     | 
    
         
            -
                    if @chunk_size && @chunk_size > file_size
         
     | 
| 
       90 
     | 
    
         
            -
                      raise ArgumentError, ":chunk_size shouldn't exceed total file size."
         
     | 
| 
       91 
     | 
    
         
            -
                    else
         
     | 
| 
       92 
     | 
    
         
            -
                      default_chunk_size = @chunk_size || [(file_size.to_f / MAX_PARTS).ceil, MIN_CHUNK_SIZE].max.to_i
         
     | 
| 
       93 
     | 
    
         
            -
                    end
         
     | 
| 
       94 
     | 
    
         
            -
                  end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                  def sort_files(files)
         
     | 
| 
       97 
     | 
    
         
            -
                    # sort file by start range count or part number
         
     | 
| 
       98 
     | 
    
         
            -
                    files.sort do |a, b|
         
     | 
| 
       99 
     | 
    
         
            -
                      a[/([^\=]+)$/].split('-')[0].to_i <=> b[/([^\=]+)$/].split('-')[0].to_i
         
     | 
| 
       100 
     | 
    
         
            -
                    end
         
     | 
| 
       101 
     | 
    
         
            -
                  end
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                  def concatenate_parts(fileparts)
         
     | 
| 
       104 
     | 
    
         
            -
                    File.open(@path, 'wb')do |output_path|
         
     | 
| 
       105 
     | 
    
         
            -
                      sort_files(fileparts).each {|part| IO.copy_stream(part, output_path)}
         
     | 
| 
       106 
     | 
    
         
            -
                    end
         
     | 
| 
       107 
     | 
    
         
            -
                  end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                  def file_batches(chunks, dir, mode)
         
     | 
| 
       110 
     | 
    
         
            -
                    batches = []
         
     | 
| 
       111 
     | 
    
         
            -
                    chunks = (1..chunks) if mode.eql? 'part_number'
         
     | 
| 
       112 
     | 
    
         
            -
                    chunks.each_slice(@thread_count) do |slice|
         
     | 
| 
       113 
     | 
    
         
            -
                      batches << map_files(slice, dir, mode)
         
     | 
| 
       114 
     | 
    
         
            -
                    end
         
     | 
| 
       115 
     | 
    
         
            -
                    batches
         
     | 
| 
       116 
     | 
    
         
            -
                  end
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
                  def map_files(slice, dir, mode)
         
     | 
| 
       119 
     | 
    
         
            -
                    case mode
         
     | 
| 
       120 
     | 
    
         
            -
                    when 'range'
         
     | 
| 
       121 
     | 
    
         
            -
                      slice.inject({}) {|h, chunk| h[chunk] = File.join(dir, chunk); h}
         
     | 
| 
       122 
     | 
    
         
            -
                    when 'part_number'
         
     | 
| 
       123 
     | 
    
         
            -
                      slice.inject({}) {|h, part| h[part] = File.join(dir, "part_number=#{part}"); h}
         
     | 
| 
       124 
     | 
    
         
            -
                    end
         
     | 
| 
       125 
     | 
    
         
            -
                  end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                  def multithreaded_get_by_ranges(chunks)
         
     | 
| 
       128 
     | 
    
         
            -
                    thread_batches(chunks, 'range')
         
     | 
| 
       129 
     | 
    
         
            -
                  end
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                  def multithreaded_get_by_parts(parts)
         
     | 
| 
       132 
     | 
    
         
            -
                    thread_batches(parts, 'part_number')
         
     | 
| 
       133 
     | 
    
         
            -
                  end
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                  def thread_batches(chunks, param)
         
     | 
| 
       136 
     | 
    
         
            -
                    # create a tmp dir under destination dir for batches
         
     | 
| 
       137 
     | 
    
         
            -
                    dir = Dir.mktmpdir(nil, File.dirname(@path))
         
     | 
| 
       138 
     | 
    
         
            -
                    batches = file_batches(chunks, dir, param)
         
     | 
| 
       139 
     | 
    
         
            -
                    parts = batches.flat_map(&:values)
         
     | 
| 
       140 
     | 
    
         
            -
                    begin
         
     | 
| 
       141 
     | 
    
         
            -
                      batches.each do |batch|
         
     | 
| 
       142 
     | 
    
         
            -
                        threads = []
         
     | 
| 
       143 
     | 
    
         
            -
                        batch.each do |chunk, file|
         
     | 
| 
       144 
     | 
    
         
            -
                          threads << Thread.new do
         
     | 
| 
       145 
     | 
    
         
            -
                            resp = @client.get_object(
         
     | 
| 
       146 
     | 
    
         
            -
                              :bucket => @bucket,
         
     | 
| 
       147 
     | 
    
         
            -
                              :key => @key,
         
     | 
| 
       148 
     | 
    
         
            -
                              param.to_sym => chunk,
         
     | 
| 
       149 
     | 
    
         
            -
                              :response_target => file
         
     | 
| 
       150 
     | 
    
         
            -
                            )
         
     | 
| 
       151 
     | 
    
         
            -
                          end
         
     | 
| 
       152 
     | 
    
         
            -
                        end
         
     | 
| 
       153 
     | 
    
         
            -
                        threads.each(&:join)
         
     | 
| 
       154 
     | 
    
         
            -
                      end
         
     | 
| 
       155 
     | 
    
         
            -
                      concatenate_parts(parts)
         
     | 
| 
       156 
     | 
    
         
            -
                    ensure
         
     | 
| 
       157 
     | 
    
         
            -
                      # clean up tmp dir
         
     | 
| 
       158 
     | 
    
         
            -
                      FileUtils.remove_entry(dir)
         
     | 
| 
       159 
     | 
    
         
            -
                    end
         
     | 
| 
       160 
     | 
    
         
            -
                  end
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                  def single_request
         
     | 
| 
       163 
     | 
    
         
            -
                    @client.get_object(
         
     | 
| 
       164 
     | 
    
         
            -
                      bucket: @bucket, key: @key, response_target: @path
         
     | 
| 
       165 
     | 
    
         
            -
                    )
         
     | 
| 
       166 
     | 
    
         
            -
                  end
         
     | 
| 
       167 
     | 
    
         
            -
                end
         
     | 
| 
       168 
     | 
    
         
            -
              end
         
     | 
| 
       169 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,75 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module Aws
         
     | 
| 
       2 
     | 
    
         
            -
              module S3
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
                # A utility class that provides an IO-like interface to a portion of
         
     | 
| 
       5 
     | 
    
         
            -
                # a file on disk.
         
     | 
| 
       6 
     | 
    
         
            -
                # @api private
         
     | 
| 
       7 
     | 
    
         
            -
                class FilePart
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  # @option options [required,String,Pathname,File,Tempfile] :source
         
     | 
| 
       10 
     | 
    
         
            -
                  # @option options [required,Integer] :offset The file part will read
         
     | 
| 
       11 
     | 
    
         
            -
                  #   starting at this byte offset.
         
     | 
| 
       12 
     | 
    
         
            -
                  # @option options [required,Integer] :size The maximum number of bytes to
         
     | 
| 
       13 
     | 
    
         
            -
                  #   read from the `:offset`.
         
     | 
| 
       14 
     | 
    
         
            -
                  def initialize(options = {})
         
     | 
| 
       15 
     | 
    
         
            -
                    @source = options[:source]
         
     | 
| 
       16 
     | 
    
         
            -
                    @first_byte = options[:offset]
         
     | 
| 
       17 
     | 
    
         
            -
                    @last_byte = @first_byte + options[:size]
         
     | 
| 
       18 
     | 
    
         
            -
                    @size = options[:size]
         
     | 
| 
       19 
     | 
    
         
            -
                    @file = nil
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                  # @return [String,Pathname,File,Tempfile]
         
     | 
| 
       23 
     | 
    
         
            -
                  attr_reader :source
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                  # @return [Integer]
         
     | 
| 
       26 
     | 
    
         
            -
                  attr_reader :first_byte
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                  # @return [Integer]
         
     | 
| 
       29 
     | 
    
         
            -
                  attr_reader :last_byte
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                  # @return [Integer]
         
     | 
| 
       32 
     | 
    
         
            -
                  attr_reader :size
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  def read(bytes = nil, output_buffer = nil)
         
     | 
| 
       35 
     | 
    
         
            -
                    open_file unless @file
         
     | 
| 
       36 
     | 
    
         
            -
                    read_from_file(bytes, output_buffer)
         
     | 
| 
       37 
     | 
    
         
            -
                  end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  def rewind
         
     | 
| 
       40 
     | 
    
         
            -
                    if @file
         
     | 
| 
       41 
     | 
    
         
            -
                      @file.seek(@first_byte)
         
     | 
| 
       42 
     | 
    
         
            -
                      @position = @first_byte
         
     | 
| 
       43 
     | 
    
         
            -
                    end
         
     | 
| 
       44 
     | 
    
         
            -
                    0
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                  def close
         
     | 
| 
       48 
     | 
    
         
            -
                    @file.close if @file
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  private
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  def open_file
         
     | 
| 
       54 
     | 
    
         
            -
                    @file = File.open(@source, 'rb')
         
     | 
| 
       55 
     | 
    
         
            -
                    rewind
         
     | 
| 
       56 
     | 
    
         
            -
                  end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                  def read_from_file(bytes, output_buffer)
         
     | 
| 
       59 
     | 
    
         
            -
                    if bytes
         
     | 
| 
       60 
     | 
    
         
            -
                      data = @file.read([remaining_bytes, bytes].min)
         
     | 
| 
       61 
     | 
    
         
            -
                      data = nil if data == ''
         
     | 
| 
       62 
     | 
    
         
            -
                    else
         
     | 
| 
       63 
     | 
    
         
            -
                      data = @file.read(remaining_bytes)
         
     | 
| 
       64 
     | 
    
         
            -
                    end
         
     | 
| 
       65 
     | 
    
         
            -
                    @position += data ? data.bytesize : 0
         
     | 
| 
       66 
     | 
    
         
            -
                    output_buffer ? output_buffer.replace(data || '') : data
         
     | 
| 
       67 
     | 
    
         
            -
                  end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                  def remaining_bytes
         
     | 
| 
       70 
     | 
    
         
            -
                    @last_byte - @position
         
     | 
| 
       71 
     | 
    
         
            -
                  end
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                end
         
     | 
| 
       74 
     | 
    
         
            -
              end
         
     | 
| 
       75 
     | 
    
         
            -
            end
         
     |