class Fog::AWS::Storage::Real

Public Class Methods

conforming_to_us_ascii!(keys, hash) click to toggle source

Create an object in an S3 bucket

@param bucket_name [String] Name of bucket to create object in @param object_name [String] Name of object to create @param data [File||String] File or String to create object from @param options [Hash] @option options Cache-Control [String] Caching behaviour @option options Content-Disposition [String] Presentational information for the object @option options Content-Encoding [String] Encoding of object data @option options Content-Length [String] Size of object in bytes (defaults to object.read.length) @option options Content-MD5 [String] Base64 encoded 128-bit MD5 digest of message @option options Content-Type [String] Standard MIME type describing contents (defaults to MIME::Types.of.first) @option options Expires [String] Cache expiry @option options x-amz-acl [String] Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read'] @option options x-amz-storage-class [String] Default is 'STANDARD', set to 'REDUCED_REDUNDANCY' for non-critical, reproducable data @option options x-amz-meta-#{name} Headers to be returned with object, note total size of request without body must be less than 8 KB. Each name, value pair must conform to US-ASCII. @option options x-amz-server-side-encryption [String] Sets HTTP header for server-side encryption. Set to 'AES256' for SSE-S3 and SSE-C. Set to 'aws:kms' for SSE-KMS @option options x-amz-server-side​-encryption​-customer-algorithm [String] Algorithm to use to when encrypting the object for SSE-C. @option options x-amz-server-side​-encryption​-customer-key [String] Encryption customer key for SSE-C @option options x-amz-server-side​-encryption​-customer-key-MD5 [String] MD5 digest of the encryption key for SSE-C @option options x-amz-server-side-encryption-aws-kms-key-id [String] KMS key ID of the encryption key for SSE-KMS @option options x-amz-server-side-encryption-context [String] Encryption context for SSE-KMS

@return [Excon::Response] response:

* headers [Hash]:
  * ETag [String] etag of new object

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html

# File lib/fog/aws/requests/storage/put_object.rb, line 34
def self.conforming_to_us_ascii!(keys, hash)
  keys.each do |k|
    v = hash[k]
    if !v.encode(::Encoding::US_ASCII, :undef => :replace).eql?(v)
      raise Excon::Errors::BadRequest.new("invalid #{k} header: value must be us-ascii")
    end
  end
end
new(options={}) click to toggle source

Initialize connection to S3

Notes

options parameter must include values for :aws_access_key_id and :aws_secret_access_key in order to create a connection

Examples

s3 = Fog::Storage.new(
  :provider => "AWS",
  :aws_access_key_id => your_aws_access_key_id,
  :aws_secret_access_key => your_aws_secret_access_key
)

Parameters

  • options<~Hash> - config arguments for connection. Defaults to {}.

Returns

  • S3 object with connection to aws.

# File lib/fog/aws/storage.rb, line 540
def initialize(options={})
  require_mime_types

  @use_iam_profile = options[:use_iam_profile]
  @instrumentor       = options[:instrumentor]
  @instrumentor_name  = options[:instrumentor_name] || 'fog.aws.storage'
  @connection_options     = options[:connection_options] || {}
  @persistent = options.fetch(:persistent, false)
  @acceleration = options.fetch(:acceleration, false)
  @signature_version = options.fetch(:aws_signature_version, 4)
  @enable_signature_v4_streaming = options.fetch(:enable_signature_v4_streaming, true)
  validate_signature_version!
  @path_style = options[:path_style]  || false

  init_max_put_chunk_size!(options)
  init_max_copy_chunk_size!(options)

  @region = options[:region] || DEFAULT_REGION

  if @endpoint = options[:endpoint]
    endpoint = URI.parse(@endpoint)
    @host = endpoint.host
    @scheme = endpoint.scheme
    @port = endpoint.port
  else
    @host       = options[:host]        || region_to_host(@region)
    @scheme     = options[:scheme]      || DEFAULT_SCHEME
    @port       = options[:port]        || DEFAULT_SCHEME_PORT[@scheme]
  end

  @host = ACCELERATION_HOST if @acceleration
  setup_credentials(options)
end

Public Instance Methods

abort_multipart_upload(bucket_name, object_name, upload_id) click to toggle source

Abort a multipart upload

@param [String] bucket_name Name of bucket to abort multipart upload on @param [String] object_name Name of object to abort multipart upload on @param [String] upload_id Id of upload to add part to

@see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadAbort.html

# File lib/fog/aws/requests/storage/abort_multipart_upload.rb, line 14
def abort_multipart_upload(bucket_name, object_name, upload_id)
  request({
    :expects    => 204,
    :headers    => {},
    :bucket_name => bucket_name,
    :object_name => object_name,
    :method     => 'DELETE',
    :query      => {'uploadId' => upload_id}
  })
end
complete_multipart_upload(bucket_name, object_name, upload_id, parts) click to toggle source

Complete a multipart upload

@param [String] bucket_name Name of bucket to complete multipart upload for @param [String] object_name Name of object to complete multipart upload for @param [String] upload_id Id of upload to add part to @param [Array<String>] parts Array of etags as Strings for parts

@return [Excon::Response]

* body [Hash]: (success)
  * Bucket [String] - bucket of new object
  * ETag [String] - etag of new object
  * Key [String] - key of new object
  * Location [String] - location of new object
* body [Hash]: (failure)
  * Code [String] - Error status code
  * Message [String] - Error description

@note This request could fail and still return +200 OK+, so it's important that you check the response. @see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html

# File lib/fog/aws/requests/storage/complete_multipart_upload.rb, line 27
def complete_multipart_upload(bucket_name, object_name, upload_id, parts)
  data = "<CompleteMultipartUpload>"
  parts.each_with_index do |part, index|
    data << "<Part>"
    data << "<PartNumber>#{index + 1}</PartNumber>"
    data << "<ETag>#{part}</ETag>"
    data << "</Part>"
  end
  data << "</CompleteMultipartUpload>"
  request({
    :body       => data,
    :expects    => 200,
    :headers    => { 'Content-Length' => data.length },
    :bucket_name => bucket_name,
    :object_name => object_name,
    :method     => 'POST',
    :parser     => Fog::Parsers::AWS::Storage::CompleteMultipartUpload.new,
    :query      => {'uploadId' => upload_id}
  })
end
copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {}) click to toggle source

Copy an object from one S3 bucket to another

@param source_bucket_name [String] Name of source bucket @param source_object_name [String] Name of source object @param target_bucket_name [String] Name of bucket to create copy in @param target_object_name [String] Name for new copy of object

@param options [Hash]: @option options [String] x-amz-metadata-directive Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE'] @option options [String] x-amz-copy_source-if-match Copies object if its etag matches this value @option options [Time] x-amz-copy_source-if-modified_since Copies object it it has been modified since this time @option options [String] x-amz-copy_source-if-none-match Copies object if its etag does not match this value @option options [Time] x-amz-copy_source-if-unmodified-since Copies object it it has not been modified since this time @option options [String] x-amz-storage-class Default is 'STANDARD', set to 'REDUCED_REDUNDANCY' for non-critical, reproducable data

@return [Excon::Response]

* body [Hash]:
  * ETag [String] - etag of new object
  * LastModified [Time] - date object was last modified

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html

# File lib/fog/aws/requests/storage/copy_object.rb, line 30
def copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {})
  headers = { 'x-amz-copy-source' => "/#{source_bucket_name}#{object_to_path(source_object_name)}" }.merge!(options)
  request({
    :expects  => 200,
    :headers  => headers,
    :bucket_name => target_bucket_name,
    :object_name => target_object_name,
    :method   => 'PUT',
    :parser   => Fog::Parsers::AWS::Storage::CopyObject.new,
  })
end
delete_bucket(bucket_name) click to toggle source

Delete an S3 bucket

@param bucket_name [String] name of bucket to delete

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETE.html

# File lib/fog/aws/requests/storage/delete_bucket.rb, line 14
def delete_bucket(bucket_name)
  request({
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'DELETE'
  })
end
delete_bucket_cors(bucket_name) click to toggle source

Deletes the cors configuration information set for the bucket.

@param bucket_name [String] name of bucket to delete cors rules from

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEcors.html

# File lib/fog/aws/requests/storage/delete_bucket_cors.rb, line 14
def delete_bucket_cors(bucket_name)
  request({
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'DELETE',
    :query    => {'cors' => nil}
  })
end
delete_bucket_lifecycle(bucket_name) click to toggle source

Delete lifecycle configuration for a bucket

@param bucket_name [String] name of bucket to delete lifecycle configuration from

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETElifecycle.html

# File lib/fog/aws/requests/storage/delete_bucket_lifecycle.rb, line 14
def delete_bucket_lifecycle(bucket_name)
  request({
            :expects  => 204,
            :headers  => {},
            :bucket_name => bucket_name,
            :method   => 'DELETE',
            :query    => {'lifecycle' => nil}
          })
end
delete_bucket_policy(bucket_name) click to toggle source

Delete policy for a bucket

@param bucket_name [String] name of bucket to delete policy from

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEpolicy.html

# File lib/fog/aws/requests/storage/delete_bucket_policy.rb, line 14
def delete_bucket_policy(bucket_name)
  request({
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'DELETE',
    :query    => {'policy' => nil}
  })
end
delete_bucket_tagging(bucket_name) click to toggle source

Delete tagging for a bucket

@param bucket_name [String] name of bucket to delete tagging from

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEtagging.html

# File lib/fog/aws/requests/storage/delete_bucket_tagging.rb, line 14
def delete_bucket_tagging(bucket_name)
  request({
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'DELETE',
    :query    => {'tagging' => nil}
  })
end
delete_bucket_website(bucket_name) click to toggle source

Delete website configuration for a bucket

@param bucket_name [String] name of bucket to delete website configuration from

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEwebsite.html

# File lib/fog/aws/requests/storage/delete_bucket_website.rb, line 14
def delete_bucket_website(bucket_name)
  request({
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'DELETE',
    :query    => {'website' => nil}
  })
end
delete_multiple_objects(bucket_name, object_names, options = {}) click to toggle source

Delete multiple objects from S3 @note For versioned deletes, options should include a version_ids hash, which

maps from filename to an array of versions.
The semantics are that for each (object_name, version) tuple, the
caller must insert the object_name and an associated version (if
desired), so for n versions, the object must be inserted n times.

@param bucket_name [String] Name of bucket containing object to delete @param object_names [Array] Array of object names to delete

@return [Excon::Response] response:

* body [Hash]:
  * DeleteResult [Array]:
    * Deleted [Hash]:
      * Key [String] - Name of the object that was deleted
      * VersionId [String] - ID for the versioned onject in case of a versioned delete
      * DeleteMarker [Boolean] - Indicates if the request accessed a delete marker
      * DeleteMarkerVersionId [String] - Version ID of the delete marker accessed
    * Error [Hash]:
      * Key [String] - Name of the object that failed to be deleted
      * VersionId [String] - ID of the versioned object that was attempted to be deleted
      * Code [String] - Status code for the result of the failed delete
      * Message [String] - Error description

@see docs.amazonwebservices.com/AmazonS3/latest/API/multiobjectdeleteapi.html

# File lib/fog/aws/requests/storage/delete_multiple_objects.rb, line 33
def delete_multiple_objects(bucket_name, object_names, options = {})
  headers = options.dup
  data = "<Delete>"
  data << "<Quiet>true</Quiet>" if headers.delete(:quiet)
  version_ids = headers.delete('versionId')
  object_names.each do |object_name|
    object_version = version_ids.nil? ? nil : version_ids[object_name]
    if object_version
      object_version = object_version.is_a?(String) ? [object_version] : object_version
      object_version.each do |version_id|
        data << "<Object>"
        data << "<Key>#{CGI.escapeHTML(object_name)}</Key>"
        data << "<VersionId>#{CGI.escapeHTML(version_id)}</VersionId>"
        data << "</Object>"
      end
    else
      data << "<Object>"
      data << "<Key>#{CGI.escapeHTML(object_name)}</Key>"
      data << "</Object>"
    end
  end
  data << "</Delete>"

  headers['Content-Length'] = data.bytesize
  headers['Content-MD5'] = Base64.encode64(OpenSSL::Digest::MD5.digest(data)).
                           gsub("\n", '')

  request({
    :body       => data,
    :expects    => 200,
    :headers    => headers,
    :bucket_name => bucket_name,
    :method     => 'POST',
    :parser     => Fog::Parsers::AWS::Storage::DeleteMultipleObjects.new,
    :query      => {'delete' => nil}
  })
end
delete_object(bucket_name, object_name, options = {}) click to toggle source

Delete an object from S3

@param bucket_name [String] Name of bucket containing object to delete @param object_name [String] Name of object to delete

@return [Excon::Response] response:

* status [Integer] - 204

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectDELETE.html

# File lib/fog/aws/requests/storage/delete_object.rb, line 15
def delete_object(bucket_name, object_name, options = {})
  if version_id = options.delete('versionId')
    query = {'versionId' => version_id}
  else
    query = {}
  end

  headers = options
  request({
    :expects    => 204,
    :headers    => headers,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method     => 'DELETE',
    :query      => query
  })
end
get_bucket(bucket_name, options = {}) click to toggle source

List information about objects in an S3 bucket

@param bucket_name [String] name of bucket to list object keys from @param options [Hash] config arguments for list. Defaults to {}. @option options delimiter [String] causes keys with the same string between the prefix

value and the first occurence of delimiter to be rolled up

@option options marker [String] limits object keys to only those that appear

lexicographically after its value.

@option options max-keys [Integer] limits number of object keys returned @option options prefix [String] limits object keys to those beginning with its value.

@return [Excon::Response] response:

* body [Hash]:
  * Delimeter [String] - Delimiter specified for query
  * IsTruncated [Boolean] - Whether or not the listing is truncated
  * Marker [String]- Marker specified for query
  * MaxKeys [Integer] - Maximum number of keys specified for query
  * Name [String] - Name of the bucket
  * Prefix [String] - Prefix specified for query
  * CommonPrefixes [Array] - Array of strings for common prefixes
  * Contents [Array]:
    * ETag [String] - Etag of object
    * Key [String] - Name of object
    * LastModified [String] - Timestamp of last modification of object
    * Owner [Hash]:
      * DisplayName [String] - Display name of object owner
      * ID [String] - Id of object owner
    * Size [Integer] - Size of object
    * StorageClass [String] - Storage class of object

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGET.html

# File lib/fog/aws/requests/storage/get_bucket.rb, line 39
def get_bucket(bucket_name, options = {})
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::GetBucket.new,
    :query    => options
  })
end
get_bucket_acl(bucket_name) click to toggle source

Get access control list for an S3 bucket

@param bucket_name [String] name of bucket to get access control list for

@return [Excon::Response] response:

* body [Hash]:
  * AccessControlPolicy [Hash]:
    * Owner [Hash]:
      * DisplayName [String] - Display name of object owner
      * ID [String] - Id of object owner
    * AccessControlList [Array]:
      * Grant [Hash]:
        * Grantee [Hash]:
          * DisplayName [String] - Display name of grantee
          * ID [String] - Id of grantee
          or
          * URI [String] - URI of group to grant access for
        * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETacl.html

# File lib/fog/aws/requests/storage/get_bucket_acl.rb, line 28
def get_bucket_acl(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::AccessControlList.new,
    :query      => {'acl' => nil}
  })
end
get_bucket_cors(bucket_name) click to toggle source

Gets the CORS configuration for an S3 bucket

@param bucket_name [String] name of bucket to get access control list for

@return [Excon::Response] response:

* body [Hash]:
  * CORSConfiguration [Array]:
    * CORSRule [Hash]:
      * AllowedHeader [String] - Which headers are allowed in a pre-flight OPTIONS request through the Access-Control-Request-Headers header.
      * AllowedMethod [String] - Identifies an HTTP method that the domain/origin specified in the rule is allowed to execute.
      * AllowedOrigin [String] - One or more response headers that you want customers to be able to access from their applications (for example, from a JavaScript XMLHttpRequest object).
      * ExposeHeader [String] - One or more headers in the response that you want customers to be able to access from their applications (for example, from a JavaScript XMLHttpRequest object).
      * ID [String] - An optional unique identifier for the rule. The ID value can be up to 255 characters long. The IDs help you find a rule in the configuration.
      * MaxAgeSeconds [Integer] - The time in seconds that your browser is to cache the preflight response for the specified resource.

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETcors.html

# File lib/fog/aws/requests/storage/get_bucket_cors.rb, line 24
def get_bucket_cors(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::CorsConfiguration.new,
    :query      => {'cors' => nil}
  })
end
get_bucket_lifecycle(bucket_name) click to toggle source

Get bucket lifecycle configuration

@param bucket_name [String] name of bucket to get lifecycle configuration for

@return [Excon::Response] response:

* body [Hash]:
  * Rules - object expire rules [Array]:
    * ID [String] - Unique identifier for the rule
    * Prefix [String] - Prefix identifying one or more objects to which the rule applies
    * Enabled [Boolean] - if rule is currently being applied
    * Days [Integer] - lifetime, in days, of the objects that are subject to the rule

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlifecycle.html

# File lib/fog/aws/requests/storage/get_bucket_lifecycle.rb, line 21
def get_bucket_lifecycle(bucket_name)
  request({
            :expects  => 200,
            :headers  => {},
            :bucket_name => bucket_name,
            :idempotent => true,
            :method   => 'GET',
            :parser   => Fog::Parsers::AWS::Storage::GetBucketLifecycle.new,
            :query    => {'lifecycle' => nil}
          })
end
get_bucket_location(bucket_name) click to toggle source

Get location constraint for an S3 bucket

@param bucket_name [String] name of bucket to get location constraint for

@return [Excon::Response] response:

* body [Hash]:
  * LocationConstraint [String] - Location constraint of the bucket

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html

# File lib/fog/aws/requests/storage/get_bucket_location.rb, line 17
def get_bucket_location(bucket_name)
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::GetBucketLocation.new,
    :query    => {'location' => nil}
  })
end
get_bucket_logging(bucket_name) click to toggle source

Get logging status for an S3 bucket

@param bucket_name [String] name of bucket to get logging status for

@return [Excon::Response] response:

* body [Hash]:
  * BucketLoggingStatus (will be empty if logging is disabled) [Hash]:
    * LoggingEnabled [Hash]:
      * TargetBucket [String] - bucket where logs are stored
      * TargetPrefix [String] - prefix logs are stored with
      * TargetGrants [Array]:
        * Grant [Hash]:
          * Grantee [Hash]:
            * DisplayName [String] - Display name of grantee
            * ID [String] - Id of grantee
            or
            * URI [String] - URI of group to grant access for
          * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlogging.html

# File lib/fog/aws/requests/storage/get_bucket_logging.rb, line 28
def get_bucket_logging(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::GetBucketLogging.new,
    :query      => {'logging' => nil}
  })
end
get_bucket_notification(bucket_name) click to toggle source

Get bucket notification configuration

@param bucket_name [String] name of bucket to get notification configuration for

@return [Excon::Response] response:

* body [Hash]:
  * Topics [Array] SNS topic configurations for the notification
    * ID [String] Unique identifier for the configuration
    * Topic [String] Amazon SNS topic ARN to which Amazon S3 will publish a message when it detects events of specified type
    * Event [String] Bucket event for which to send notifications
  * Queues [Array] SQS queue configurations for the notification
    * ID [String] Unique identifier for the configuration
    * Queue [String] Amazon SQS queue ARN to which Amazon S3 will publish a message when it detects events of specified type
    * Event [String] Bucket event for which to send notifications
  * CloudFunctions [Array] AWS Lambda notification configurations
    * ID [String] Unique identifier for the configuration
    * CloudFunction [String] Lambda cloud function ARN that Amazon S3 can invoke when it detects events of the specified type
    * InvocationRole [String] IAM role ARN that Amazon S3 can assume to invoke the specified cloud function on your behalf
    * Event [String] Bucket event for which to send notifications

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETnotification.html

# File lib/fog/aws/requests/storage/get_bucket_notification.rb, line 28
def get_bucket_notification(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::GetBucketNotification.new,
    :query      => {'notification' => nil}
  })
end
get_bucket_object_versions(bucket_name, options = {}) click to toggle source

List information about object versions in an S3 bucket

@param bucket_name [String] name of bucket to list object keys from @param options [Hash] config arguments for list @option options delimiter [String] causes keys with the same string between the prefix value and the first occurence of delimiter to be rolled up @option options key-marker [String] limits object keys to only those that appear lexicographically after its value. @option options max-keys [Integer] limits number of object keys returned @option options prefix [String] limits object keys to those beginning with its value. @option options version-id-marker [String] limits object versions to only those that appear lexicographically after its value

@return [Excon::Response] response:

* body [Hash]:
  * Delimeter [String] - Delimiter specified for query
  * KeyMarker [String] - Key marker specified for query
  * MaxKeys [Integer] - Maximum number of keys specified for query
  * Name [String] - Name of the bucket
  * Prefix [String] - Prefix specified for query
  * VersionIdMarker [String] - Version id marker specified for query
  * IsTruncated [Boolean] - Whether or not this is the totality of the bucket
  * Versions [Array]:
    * DeleteMarker [Hash]:
      * IsLatest [Boolean] - Whether or not this is the latest version
      * Key [String] - Name of object
      * LastModified [String]: Timestamp of last modification of object
      * Owner [Hash]:
        * DisplayName [String] - Display name of object owner
        * ID [String] - Id of object owner
      * VersionId [String] - The id of this version
    or
    * Version [Hash]:
      * ETag [String]: Etag of object
      * IsLatest [Boolean] - Whether or not this is the latest version
      * Key [String] - Name of object
      * LastModified [String]: Timestamp of last modification of object
      * Owner [Hash]:
        * DisplayName [String] - Display name of object owner
        * ID [String] - Id of object owner
      * Size [Integer] - Size of object
      * StorageClass [String] - Storage class of object
      * VersionId [String] - The id of this version

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETVersion.html

# File lib/fog/aws/requests/storage/get_bucket_object_versions.rb, line 50
def get_bucket_object_versions(bucket_name, options = {})
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::GetBucketObjectVersions.new,
    :query    => {'versions' => nil}.merge!(options)          })
end
get_bucket_policy(bucket_name) click to toggle source

Get bucket policy for an S3 bucket

@param bucket_name [String] name of bucket to get policy for

@return [Excon::Response] response:

* body [Hash] - policy document

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETpolicy.html

# File lib/fog/aws/requests/storage/get_bucket_policy.rb, line 14
def get_bucket_policy(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  response = request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :query      => {'policy' => nil}
  })
  response.body = Fog::JSON.decode(response.body) unless response.body.nil?
end
get_bucket_tagging(bucket_name) click to toggle source

Get tags for an S3 bucket

@param bucket_name [String] name of bucket to get tags for

@return [Excon::Response] response:

* body [Hash]:
  * BucketTagging [Hash]:
    * Key [String] - tag key
    * Value [String] - tag value

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETtagging.html

# File lib/fog/aws/requests/storage/get_bucket_tagging.rb, line 18
def get_bucket_tagging(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::GetBucketTagging.new,
    :query      => {'tagging' => nil}
  })
end
get_bucket_versioning(bucket_name) click to toggle source

Get versioning status for an S3 bucket

@param bucket_name [String] name of bucket to get versioning status for

@return [Excon::Response] response:

* body [Hash]:
  * VersioningConfiguration [Hash]:
    * Status [String] - Versioning status in ['Enabled', 'Suspended', nil]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETversioningStatus.html

# File lib/fog/aws/requests/storage/get_bucket_versioning.rb, line 18
def get_bucket_versioning(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::GetBucketVersioning.new,
    :query      => {'versioning' => nil}
  })
end
get_bucket_website(bucket_name) click to toggle source

Get website configuration for an S3 bucket

@param bucket_name [String] name of bucket to get website configuration for

@return [Excon::Response] response:

* body [Hash]:
  * IndexDocument [Hash]:
    * Suffix [String] - Suffix appended when directory is requested
  * ErrorDocument [Hash]:
    * Key [String] - Object key to return for 4XX class errors

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETwebsite.html

# File lib/fog/aws/requests/storage/get_bucket_website.rb, line 21
def get_bucket_website(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::GetBucketWebsite.new,
    :query      => {'website' => nil}
  })
end
get_object(bucket_name, object_name, options = {}, &block) click to toggle source

Get an object from S3

@param bucket_name [String] Name of bucket to read from @param object_name [String] Name of object to read @param options [Hash] @option options If-Match [String] Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed). @option options If-Modified-Since [Time] Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified). @option options If-None-Match [String] Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified) @option options If-Unmodified-Since [Time] Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed). @option options Range [String] Range of object to download @option options versionId [String] specify a particular version to retrieve @option options query specify additional query string

@return [Excon::Response] response:

* body [String]- Contents of object
* headers [Hash]:
  * Content-Length [String] - Size of object contents
  * Content-Type [String] - MIME type of object
  * ETag [String] - Etag of object
  * Last-Modified [String] - Last modified timestamp for object

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html

# File lib/fog/aws/requests/storage/get_object.rb, line 28
def get_object(bucket_name, object_name, options = {}, &block)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end

  params = { :headers => {} }

  params[:query] = options.delete('query') || {}

  if version_id = options.delete('versionId')
    params[:query] = params[:query].merge({'versionId' => version_id})
  end
  params[:headers].merge!(options)
  if options['If-Modified-Since']
    params[:headers]['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header
  end
  if options['If-Unmodified-Since']
    params[:headers]['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header
  end

  idempotent = true
  if block_given?
    params[:response_block] = Proc.new(&block)
    idempotent = false
  end

  request(params.merge!({
    :expects  => [ 200, 206 ],
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => idempotent,
    :method   => 'GET',
  }))
end
get_object_acl(bucket_name, object_name, options = {}) click to toggle source

Get access control list for an S3 object

@param bucket_name [String] name of bucket containing object @param object_name [String] name of object to get access control list for @param options [Hash] @option options versionId [String] specify a particular version to retrieve

@return [Excon::Response] response:

* body [Hash]:
  * [AccessControlPolicy [Hash]:
    * Owner [Hash]:
      * DisplayName [String] - Display name of object owner
      * ID [String] - Id of object owner
    * AccessControlList [Array]:
      * Grant [Hash]:
        * Grantee [Hash]:
          * DisplayName [String] - Display name of grantee
          * ID [String] - Id of grantee
          or
          * URI [String] - URI of group to grant access for
        * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETacl.html

# File lib/fog/aws/requests/storage/get_object_acl.rb, line 31
def get_object_acl(bucket_name, object_name, options = {})
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end
  query = {'acl' => nil}
  if version_id = options.delete('versionId')
    query['versionId'] = version_id
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method     => 'GET',
    :parser     => Fog::Parsers::AWS::Storage::AccessControlList.new,
    :query      => query
  })
end
get_object_tagging(bucket_name, object_name) click to toggle source

Get tags for an S3 object

@param bucket_name [String] Name of bucket to read from @param object_name [String] Name of object to get tags for

@return [Excon::Response] response:

* body [Hash]:
  * ObjectTagging [Hash]:
    * Key [String] - tag key
    * Value [String] - tag value

@see docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html

# File lib/fog/aws/requests/storage/get_object_tagging.rb, line 19
def get_object_tagging(bucket_name, object_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end

  request({
    :expects => 200,
    :headers => {},
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method => 'GET',
    :parser => Fog::Parsers::AWS::Storage::GetObjectTagging.new,
    :query => {'tagging' => nil}
  })
end
get_object_torrent(bucket_name, object_name) click to toggle source

Get torrent for an S3 object

@param bucket_name [String] name of bucket containing object @param object_name [String] name of object to get torrent for

@return [Excon::Response] response:

* body [Hash]:
  * AccessControlPolicy [Hash:
    * Owner [Hash]:
      * DisplayName [String] - Display name of object owner
      * ID [String] - Id of object owner
    * AccessControlList [Array]:
      * Grant [Hash]:
        * Grantee [Hash]:
          * DisplayName [String] - Display name of grantee
          * ID [String] - Id of grantee
        * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETtorrent.html

# File lib/fog/aws/requests/storage/get_object_torrent.rb, line 25
def get_object_torrent(bucket_name, object_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end
  request({
    :expects    => 200,
    :headers    => {},
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method     => 'GET',
    :query      => {'torrent' => nil}
  })
end
get_request_payment(bucket_name) click to toggle source

Get configured payer for an S3 bucket

@param bucket_name [String] name of bucket to get payer for

@return [Excon::Response] response:

* body [Hash]:
  * Payer [String] - Specifies who pays for download and requests

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTrequestPaymentGET.html

# File lib/fog/aws/requests/storage/get_request_payment.rb, line 17
def get_request_payment(bucket_name)
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::GetRequestPayment.new,
    :query    => {'requestPayment' => nil}
  })
end
get_service() click to toggle source

List information about S3 buckets for authorized user

@return [Excon::Response] response:

* body [Hash]:
  * Buckets [Hash]:
    * Name [String] - Name of bucket
    * CreationTime [Time] - Timestamp of bucket creation
  * Owner [Hash]:
    * DisplayName [String] - Display name of bucket owner
    * ID [String] - Id of bucket owner

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTServiceGET.html

# File lib/fog/aws/requests/storage/get_service.rb, line 20
def get_service
  request({
    :expects  => 200,
    :headers  => {},
    :host     => 's3.amazonaws.com',
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::GetService.new
  })
end
head_bucket(bucket_name) click to toggle source

Get headers for an S3 bucket, used to verify if it exists and if you have permission to access it

@param bucket_name [String] Name of bucket to read from

@return [Excon::Response] 200 response implies it exists, 404 does not exist, 403 no permissions

* body [String] Empty
* headers [Hash]:
  * Content-Type [String] - MIME type of object

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketHEAD.html

# File lib/fog/aws/requests/storage/head_bucket.rb, line 16
def head_bucket(bucket_name)
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  request({
    :expects    => 200,
    :bucket_name => bucket_name,
    :idempotent => true,
    :method     => 'HEAD',
  })
end
head_object(bucket_name, object_name, options={}) click to toggle source

Get headers for an object from S3

@param bucket_name [String] Name of bucket to read from @param object_name [String] Name of object to read @param options [Hash]: @option options [String] If-Match Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed). @option options [Time] If-Modified-Since Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified). @option options [String] If-None-Match Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified) @option options [Time] If-Unmodified-Since Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed). @option options [String] Range Range of object to download @option options [String] versionId specify a particular version to retrieve

@return [Excon::Response] response:

* body [String] Contents of object
* headers [Hash]:
  * Content-Length [String] - Size of object contents
  * Content-Type [String] - MIME type of object
  * ETag [String] - Etag of object
  * Last-Modified - [String] Last modified timestamp for object

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectHEAD.html

# File lib/fog/aws/requests/storage/head_object.rb, line 27
def head_object(bucket_name, object_name, options={})
  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end
  unless object_name
    raise ArgumentError.new('object_name is required')
  end
  if version_id = options.delete('versionId')
    query = {'versionId' => version_id}
  end
  headers = {}
  headers['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header if options['If-Modified-Since']
  headers['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header if options['If-Modified-Since']
  headers.merge!(options)
  request({
    :expects    => 200,
    :headers    => headers,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method     => 'HEAD',
    :query      => query
  })
end
initiate_multipart_upload(bucket_name, object_name, options = {}) click to toggle source

Initiate a multipart upload to an S3 bucket

@param bucket_name [String] Name of bucket to create object in @param object_name [String] Name of object to create @param options [Hash]: @option options [String] Cache-Control Caching behaviour @option options [String] Content-Disposition Presentational information for the object @option options [String] Content-Encoding Encoding of object data @option options [String] Content-MD5 Base64 encoded 128-bit MD5 digest of message (defaults to Base64 encoded MD5 of object.read) @option options [String] Content-Type Standard MIME type describing contents (defaults to MIME::Types.of.first) @option options [String] x-amz-acl Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read'] @option options [String] x-amz-meta-#{name} Headers to be returned with object, note total size of request without body must be less than 8 KB.

@return [Excon::Response] response:

* body [Hash]:
  * Bucket [String] - Bucket where upload was initiated
  * Key [String] - Object key where the upload was initiated
  * UploadId [String] - Id for initiated multipart upload

@see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html

# File lib/fog/aws/requests/storage/initiate_multipart_upload.rb, line 28
def initiate_multipart_upload(bucket_name, object_name, options = {})
  request({
    :expects    => 200,
    :headers    => options,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :method     => 'POST',
    :parser     => Fog::Parsers::AWS::Storage::InitiateMultipartUpload.new,
    :query      => {'uploads' => nil}
  })
end
list_multipart_uploads(bucket_name, options = {}) click to toggle source

List multipart uploads for a bucket

@param [String] bucket_name Name of bucket to list multipart uploads for @param [Hash] options config arguments for list. Defaults to {}. @option options [String] key-marker limits parts to only those that appear lexicographically after this key. @option options [Integer] max-uploads limits number of uploads returned @option options [String] upload-id-marker limits uploads to only those that appear lexicographically after this upload id.

@return [Excon::Response] response:

* body [Hash]:
  * Bucket [String] Bucket where the multipart upload was initiated
  * IsTruncated [Boolean] Whether or not the listing is truncated
  * KeyMarker [String] first key in list, only upload ids after this lexographically will appear
  * MaxUploads [Integer] Maximum results to return
  * NextKeyMarker [String] last key in list, for further pagination
  * NextUploadIdMarker [String] last key in list, for further pagination
  * Upload [Hash]:
    * Initiated [Time] Time when upload was initiated
    * Initiator [Hash]:
      * DisplayName [String] Display name of upload initiator
      * ID [String] Id of upload initiator
    * Key [String] Key where multipart upload was initiated
    * Owner [Hash]:
      * DisplayName [String] Display name of upload owner
      * ID [String] Id of upload owner
    * StorageClass [String] Storage class of object
    * UploadId [String] upload id of upload containing part
  * UploadIdMarker [String] first key in list, only upload ids after this lexographically will appear

@see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListMPUpload.html

# File lib/fog/aws/requests/storage/list_multipart_uploads.rb, line 38
def list_multipart_uploads(bucket_name, options = {})
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::ListMultipartUploads.new,
    :query    => options.merge!({'uploads' => nil})
  })
end
list_parts(bucket_name, object_name, upload_id, options = {}) click to toggle source

List parts for a multipart upload

@param bucket_name [String] Name of bucket to list parts for @param object_name [String] Name of object to list parts for @param upload_id [String] upload id to list objects for @param options [Hash] config arguments for list. Defaults to {}. @option options max-parts [Integer] limits number of parts returned @option options part-number-marker [String] limits parts to only those that appear lexicographically after this part number.

@return [Excon::Response] response:

* body [Hash]:
  * Bucket [string] Bucket where the multipart upload was initiated
  * Initiator [Hash]:
    * DisplayName [String] Display name of upload initiator
    * ID [String] Id of upload initiator
  * IsTruncated [Boolean] Whether or not the listing is truncated
  * Key [String] Key where multipart upload was initiated
  * MaxParts [String] maximum number of replies alllowed in response
  * NextPartNumberMarker [String] last item in list, for further pagination
  * Part [Array]:
    * ETag [String] ETag of part
    * LastModified [Timestamp] Last modified for part
    * PartNumber [String] Part number for part
    * Size [Integer] Size of part
  * PartNumberMarker [String] Part number after which listing begins
  * StorageClass [String] Storage class of object
  * UploadId [String] upload id of upload containing part

@see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListParts.html

# File lib/fog/aws/requests/storage/list_parts.rb, line 37
def list_parts(bucket_name, object_name, upload_id, options = {})
  options['uploadId'] = upload_id
  request({
    :expects  => 200,
    :headers  => {},
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method   => 'GET',
    :parser   => Fog::Parsers::AWS::Storage::ListParts.new,
    :query    => options.merge!({'uploadId' => upload_id})
  })
end
post_object_restore(bucket_name, object_name, days = 100000) click to toggle source

Restore an object from Glacier to its original S3 path

@param bucket_name [String] Name of bucket containing object @param object_name [String] Name of object to restore @option days [Integer] Number of days to restore object for. Defaults to 100000 (a very long time)

@return [Excon::Response] response:

* status [Integer] 200 (OK) Object is previously restored
* status [Integer] 202 (Accepted) Object is not previously restored
* status [Integer] 409 (Conflict) Restore is already in progress

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html

# File lib/fog/aws/requests/storage/post_object_restore.rb, line 18
def post_object_restore(bucket_name, object_name, days = 100000)
  raise ArgumentError.new('bucket_name is required') unless bucket_name
  raise ArgumentError.new('object_name is required') unless object_name

  data = '<RestoreRequest xmlns="http://s3.amazonaws.com/doc/2006-3-01"><Days>' + days.to_s + '</Days></RestoreRequest>'

  headers = {}
  headers['Content-MD5'] = Base64.encode64(OpenSSL::Digest::MD5.digest(data)).strip
  headers['Content-Type'] = 'application/xml'
  headers['Date'] = Fog::Time.now.to_date_header

  request({
    :headers  => headers,
    :bucket_name => bucket_name,
    :expects  => [200, 202, 409],
    :body     => data,
    :method   => 'POST',
    :query    => {'restore' => nil},
    :object_name  => object_name
  })
end
put_bucket(bucket_name, options = {}) click to toggle source

Create an S3 bucket

@param bucket_name [String] name of bucket to create @option options [Hash] config arguments for bucket. Defaults to {}. @option options LocationConstraint [Symbol] sets the location for the bucket @option options x-amz-acl [String] Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']

@return [Excon::Response] response:

* status [Integer] 200

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html

# File lib/fog/aws/requests/storage/put_bucket.rb, line 17
        def put_bucket(bucket_name, options = {})
          if location_constraint = options.delete('LocationConstraint')
            data =
<<-DATA
  <CreateBucketConfiguration>
    <LocationConstraint>#{location_constraint}</LocationConstraint>
  </CreateBucketConfiguration>
DATA
          else
            data = nil
          end
          request({
            :expects    => 200,
            :body       => data,
            :headers    => options,
            :idempotent => true,
            :bucket_name => bucket_name,
            :method     => 'PUT'
          })
        end
put_bucket_acl(bucket_name, acl) click to toggle source

Change access control list for an S3 bucket

@param bucket_name [String] name of bucket to modify @param acl [Hash]

* Owner [Hash]:
  * ID [String]: id of owner
  * DisplayName [String]: display name of owner
* AccessControlList [Array]:
  * Grantee [Hash]:
    * DisplayName [String] Display name of grantee
    * ID [String] Id of grantee
    or
    * EmailAddress [String] Email address of grantee
    or
    * URI [String] URI of group to grant access for
  * Permission [String] Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]
  • acl [String] Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTacl.html

# File lib/fog/aws/requests/storage/put_bucket_acl.rb, line 27
def put_bucket_acl(bucket_name, acl)
  data = ""
  headers = {}

  if acl.is_a?(Hash)
    data = Fog::AWS::Storage.hash_to_acl(acl)
  else
    if !['private', 'public-read', 'public-read-write', 'authenticated-read'].include?(acl)
      raise Excon::Errors::BadRequest.new('invalid x-amz-acl')
    end
    headers['x-amz-acl'] = acl
  end

  headers['Content-MD5'] = Base64.encode64(OpenSSL::Digest::MD5.digest(data)).strip
  headers['Content-Type'] = 'application/json'
  headers['Date'] = Fog::Time.now.to_date_header

  request({
    :body     => data,
    :expects  => 200,
    :headers  => headers,
    :bucket_name => bucket_name,
    :method   => 'PUT',
    :query    => {'acl' => nil}
  })
end
put_bucket_cors(bucket_name, cors) click to toggle source

Sets the cors configuration for your bucket. If the configuration exists, Amazon S3 replaces it.

@param bucket_name [String] name of bucket to modify @param cors [Hash]

* CORSConfiguration [Array]:
  * ID [String]: A unique identifier for the rule.
  * AllowedMethod [String]: An HTTP method that you want to allow the origin to execute.
  * AllowedOrigin [String]: An origin that you want to allow cross-domain requests from.
  * AllowedHeader [String]: Specifies which headers are allowed in a pre-flight OPTIONS request via the Access-Control-Request-Headers header.
  * MaxAgeSeconds [String]: The time in seconds that your browser is to cache the preflight response for the specified resource.
  * ExposeHeader [String]: One or more headers in the response that you want customers to be able to access from their applications.

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTcors.html

# File lib/fog/aws/requests/storage/put_bucket_cors.rb, line 21
def put_bucket_cors(bucket_name, cors)
  data = Fog::AWS::Storage.hash_to_cors(cors)

  headers = {}
  headers['Content-MD5'] = Base64.encode64(OpenSSL::Digest::MD5.digest(data)).strip
  headers['Content-Type'] = 'application/json'
  headers['Date'] = Fog::Time.now.to_date_header

  request({
    :body     => data,
    :expects  => 200,
    :headers  => headers,
    :bucket_name => bucket_name,
    :method   => 'PUT',
    :query    => {'cors' => nil}
  })
end
put_bucket_lifecycle(bucket_name, lifecycle) click to toggle source

Change lifecycle configuration for an S3 bucket

@param bucket_name [String] name of bucket to set lifecycle configuration for

  • lifecycle [Hash]:

    • Rules [Array] object expire rules

      • ID [String] Unique identifier for the rule

      • Prefix [String] Prefix identifying one or more objects to which the rule applies

      • Enabled [Boolean] if rule is currently being applied

      • NoncurrentVersion]Expiration [Hash

        Container for the object expiration rule.

        • Noncurrent]Days [Integer

          lifetime, in days, of the objects that are subject to the rule

        • Date [Date] Indicates when the specific rule take effect. The date value must conform to the ISO 8601 format. The time is always midnight UTC.

      • NoncurrentVersion]Transition [Hash

        Container for the transition rule that describes when objects transition

        to the Glacier storage class

        • Noncurrent]Days [Integer

          lifetime, in days, of the objects that are subject to the rule

        • Date [Date] Indicates when the specific rule take effect. The date value must conform to the ISO 8601 format. The time is always midnight UTC.

        • StorageClass [String] Indicates the Amazon S3 storage class to which you want the object to transition to.

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html

# File lib/fog/aws/requests/storage/put_bucket_lifecycle.rb, line 28
def put_bucket_lifecycle(bucket_name, lifecycle)
  builder = Nokogiri::XML::Builder.new do
    LifecycleConfiguration {
      lifecycle['Rules'].each do |rule|
        Rule {
          ID rule['ID']
          Prefix rule['Prefix']
          Status rule['Enabled'] ? 'Enabled' : 'Disabled'
          unless (rule['Expiration'] or rule['Transition'] or rule['NoncurrentVersionExpiration'] or rule['NoncurrentVersionTransition'])
            Expiration { Days rule['Days'] }
          else
            if rule['Expiration']
              if rule['Expiration']['Days']
                Expiration { Days rule['Expiration']['Days'] }
              elsif rule['Expiration']['Date']
                Expiration { Date rule['Expiration']['Date'].is_a?(Time) ? rule['Expiration']['Date'].utc.iso8601 : Time.parse(rule['Expiration']['Date']).utc.iso8601 }
              end
            end
            if rule['NoncurrentVersionExpiration']
              if rule['NoncurrentVersionExpiration']['NoncurrentDays']
                NoncurrentVersionExpiration { NoncurrentDays rule['NoncurrentVersionExpiration']['NoncurrentDays'] }
              elsif rule['NoncurrentVersionExpiration']['Date']
                NoncurrentVersoinExpiration {
                  if Date rule['NoncurrentVersionExpiration']['Date'].is_a?(Time)
                    rule['NoncurrentVersionExpiration']['Date'].utc.iso8601
                  else
                    Time.parse(rule['NoncurrentVersionExpiration']['Date']).utc.iso8601
                  end
                }
              end
            end
            if rule['Transition']
              Transition {
                if rule['Transition']['Days']
                  Days rule['Transition']['Days']
                elsif rule['Transition']['Date']
                  Date rule['Transition']['Date'].is_a?(Time) ? time.utc.iso8601 : Time.parse(time).utc.iso8601
                end
                StorageClass rule['Transition']['StorageClass'].nil? ? 'GLACIER' : rule['Transition']['StorageClass']
              }
            end
            if rule['NoncurrentVersionTransition']
              NoncurrentVersionTransition {
                if rule['NoncurrentVersionTransition']['NoncurrentDays']
                  NoncurrentDays rule['NoncurrentVersionTransition']['NoncurrentDays']
                elsif rule['NoncurrentVersionTransition']['Date']
                  Date rule['NoncurrentVersionTransition']['Date'].is_a?(Time) ? time.utc.iso8601 : Time.parse(time).utc.iso8601
                end
                StorageClass rule['NoncurrentVersionTransition']['StorageClass'].nil? ? 'GLACIER' : rule['NoncurrentVersionTransition']['StorageClass']
              }
            end
          end
        }
      end
    }
  end
  body = builder.to_xml
  body.gsub! /<([^<>]+)\/>/, '<\1></\1>'
  request({
            :body     => body,
            :expects  => 200,
            :headers  => {'Content-MD5' => Base64.encode64(OpenSSL::Digest::MD5.digest(body)).chomp!,
              'Content-Type' => 'application/xml'},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'lifecycle' => nil}
          })
end
put_bucket_logging(bucket_name, logging_status) click to toggle source

Change logging status for an S3 bucket

@param bucket_name [String] name of bucket to modify @param logging_status [Hash]:

* LoggingEnabled [Hash]: logging options or {} to disable
  * Owner [Hash]:
    * ID [String]: id of owner
    * DisplayName [String]: display name of owner
  * AccessControlList [Array]:
    * Grantee [Hash]:
      * DisplayName [String] Display name of grantee
      * ID [String] Id of grantee
      or
      * EmailAddress [String] Email address of grantee
      or
      * URI [String] URI of group to grant access for
    * Permission [String] Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTlogging.html

# File lib/fog/aws/requests/storage/put_bucket_logging.rb, line 25
        def put_bucket_logging(bucket_name, logging_status)
          if logging_status['LoggingEnabled'].empty?
            data =
<<-DATA
<BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01" />
DATA
          else
            data =
<<-DATA
<BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01">
  <LoggingEnabled>
    <TargetBucket>#{logging_status['LoggingEnabled']['TargetBucket']}</TargetBucket>
    <TargetPrefix>#{logging_status['LoggingEnabled']['TargetBucket']}</TargetPrefix>
    <TargetGrants>
DATA

            logging_status['AccessControlList'].each do |grant|
              data << "      <Grant>"
              type = case grant['Grantee'].keys.sort
              when ['DisplayName', 'ID']
                'CanonicalUser'
              when ['EmailAddress']
                'AmazonCustomerByEmail'
              when ['URI']
                'Group'
              end
              data << "        <Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"#{type}\">"
              for key, value in grant['Grantee']
                data << "          <#{key}>#{value}</#{key}>"
              end
              data << "        </Grantee>"
              data << "        <Permission>#{grant['Permission']}</Permission>"
              data << "      </Grant>"
            end

            data <<
<<-DATA
    </TargetGrants>
  </LoggingEnabled>
</BucketLoggingStatus>
DATA
          end

          request({
            :body     => data,
            :expects  => 200,
            :headers  => {},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'logging' => nil}
          })
        end
put_bucket_notification(bucket_name, notification) click to toggle source

Change notification configuration for an S3 bucket

@param bucket_name [String] name of bucket to set notification configuration for

  • notications [Hash]:

    • Topics [Array] SNS topic configurations for the notification

      • ID [String] Unique identifier for the configuration

      • Topic [String] Amazon SNS topic ARN to which Amazon S3 will publish a message when it detects events of specified type

      • Event [String] Bucket event for which to send notifications

    • Queues [Array] SQS queue configurations for the notification

      • ID [String] Unique identifier for the configuration

      • Queue [String] Amazon SQS queue ARN to which Amazon S3 will publish a message when it detects events of specified type

      • Event [String] Bucket event for which to send notifications

    • CloudFunctions [Array] AWS Lambda notification configurations

      • ID [String] Unique identifier for the configuration

      • CloudFunction [String] Lambda cloud function ARN that Amazon S3 can invoke when it detects events of the specified type

      • InvocationRole [String] IAM role ARN that Amazon S3 can assume to invoke the specified cloud function on your behalf

      • Event [String] Bucket event for which to send notifications

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTnotification.html

# File lib/fog/aws/requests/storage/put_bucket_notification.rb, line 25
def put_bucket_notification(bucket_name, notification)
  builder = Nokogiri::XML::Builder.new do
    NotificationConfiguration do
      notification.fetch('Topics', []).each do |topic|
        TopicConfiguration do
          Id    topic['Id']
          Topic topic['Topic']
          Event topic['Event']
        end
      end
      notification.fetch('Queues', []).each do |queue|
        QueueConfiguration do
          Id    queue['Id']
          Queue queue['Queue']
          Event queue['Event']
        end
      end
      notification.fetch('CloudFunctions', []).each do |func|
        CloudFunctionConfiguration do
          Id             func['Id']
          CloudFunction  func['CloudFunction']
          InvocationRole func['InvocationRole']
          Event          func['Event']
        end
      end
    end
  end
  body = builder.to_xml
  body.gsub!(/<([^<>]+)\/>/, '<\1></\1>')
  request({
    :body     => body,
    :expects  => 200,
    :headers  => {'Content-MD5' => Base64.encode64(OpenSSL::Digest::MD5.digest(body)).chomp!,
      'Content-Type' => 'application/xml'},
    :bucket_name => bucket_name,
    :method   => 'PUT',
    :query    => {'notification' => nil}
  })
end
put_bucket_policy(bucket_name, policy) click to toggle source

Change bucket policy for an S3 bucket

@param bucket_name [String] name of bucket to modify @param policy [Hash] policy document

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTpolicy.html

# File lib/fog/aws/requests/storage/put_bucket_policy.rb, line 12
def put_bucket_policy(bucket_name, policy)
  request({
    :body     => Fog::JSON.encode(policy),
    :expects  => 204,
    :headers  => {},
    :bucket_name => bucket_name,
    :method   => 'PUT',
    :query    => {'policy' => nil}
  })
end
put_bucket_tagging(bucket_name, tags) click to toggle source

Change tag set for an S3 bucket

@param bucket_name [String] name of bucket to modify @param tags [Hash]:

* Key [String]: tag key
* Value [String]: tag value

@see docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTtagging.html

# File lib/fog/aws/requests/storage/put_bucket_tagging.rb, line 14
        def put_bucket_tagging(bucket_name, tags)
          tagging = tags.map do |k,v|
            "<Tag><Key>#{k}</Key><Value>#{v}</Value></Tag>"
          end.join("\n")
          data =
<<-DATA
<Tagging xmlns="http://doc.s3.amazonaws.com/2006-03-01" >
  <TagSet>
    #{tagging}
  </TagSet>
</Tagging>
DATA

          request({
            :body     => data,
            :expects  => 204,
            :headers  => {'Content-MD5' => Base64.encode64(OpenSSL::Digest::MD5.digest(data)).chomp!, 'Content-Type' => 'application/xml'},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'tagging' => nil}
          })
        end
put_bucket_versioning(bucket_name, status) click to toggle source

Change versioning status for an S3 bucket

@param bucket_name [String] name of bucket to modify @param status [String] Status to change to in ['Enabled', 'Suspended']

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTVersioningStatus.html

# File lib/fog/aws/requests/storage/put_bucket_versioning.rb, line 12
        def put_bucket_versioning(bucket_name, status)
          data =
<<-DATA
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Status>#{status}</Status>
</VersioningConfiguration>
DATA

          request({
            :body     => data,
            :expects  => 200,
            :headers  => {},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'versioning' => nil}
          })
        end
put_bucket_website(bucket_name, options, options_to_be_deprecated = {}) click to toggle source

Change website configuration for an S3 bucket

@param bucket_name [String] name of bucket to modify @param options [Hash] @option options RedirectAllRequestsTo [String] Host name to redirect all requests to - if this is set, other options are ignored @option options IndexDocument [String] suffix to append to requests for the bucket @option options ErrorDocument [String] key to use for 4XX class errors

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html

# File lib/fog/aws/requests/storage/put_bucket_website.rb, line 15
        def put_bucket_website(bucket_name, options, options_to_be_deprecated = {})
          options ||= {}

          # Method used to be called with the suffix as the second parameter. Warn user that this is not the case any more and move on
          if options.is_a?(String)
            Fog::Logger.deprecation("put_bucket_website with #{options.class} param is deprecated, use put_bucket_website('#{bucket_name}', :IndexDocument => '#{options}') instead [light_black](#{caller.first})[/]")
            options = { :IndexDocument => options }
          end

          # Parameter renamed from "key" to "ErrorDocument"
          if options_to_be_deprecated[:key]
            Fog::Logger.deprecation("put_bucket_website with three parameters is deprecated, use put_bucket_website('#{bucket_name}', :ErrorDocument => '#{options_to_be_deprecated[:key]}') instead [light_black](#{caller.first})[/]")
            options[:ErrorDocument] = options_to_be_deprecated[:key]
          end

          options.merge!(options_to_be_deprecated) { |key, o1, o2| o1 }

          data = "<WebsiteConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">"

          if options[:RedirectAllRequestsTo]
            # Redirect precludes all other options
            data << <<-DATA
                      <RedirectAllRequestsTo>
                        <HostName>#{options[:RedirectAllRequestsTo]}</HostName>
                      </RedirectAllRequestsTo>
                    DATA
          else

            if options[:IndexDocument]
            data << <<-DATA
                      <IndexDocument>
                        <Suffix>#{options[:IndexDocument]}</Suffix>
                      </IndexDocument>
                    DATA
            end

            if options[:ErrorDocument]
              data << <<-DATA
                        <ErrorDocument>
                          <Key>#{options[:ErrorDocument]}</Key>
                        </ErrorDocument>
                      DATA
            end
          end

          data << '</WebsiteConfiguration>'
          request({
            :body     => data,
            :expects  => 200,
            :headers  => {},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'website' => nil}
          })
        end
put_object(bucket_name, object_name, data, options = {}) click to toggle source
# File lib/fog/aws/requests/storage/put_object.rb, line 43
def put_object(bucket_name, object_name, data, options = {})
  data = Fog::Storage.parse_data(data)
  headers = data[:headers].merge!(options)
  self.class.conforming_to_us_ascii! headers.keys.grep(/^x-amz-meta-/), headers

  request({
    :body       => data[:body],
    :expects    => 200,
    :headers    => headers,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :idempotent => true,
    :method     => 'PUT',
  })
end
put_object_acl(bucket_name, object_name, acl, options = {}) click to toggle source

Change access control list for an S3 object

@param [String] bucket_name name of bucket to modify @param [String] object_name name of object to get access control list for @param [Hash] acl

* Owner [Hash]
  * ID [String] id of owner
  * DisplayName [String] display name of owner
* AccessControlList [Array]
  * Grantee [Hash]
    * DisplayName [String] Display name of grantee
    * ID [String] Id of grantee
    or
    * EmailAddress [String] Email address of grantee
    or
    * URI [String] URI of group to grant access for
  * Permission [String] Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]

@param [String] acl Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read'] @param [Hash] options @option options [String] versionId specify a particular version to retrieve

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUTacl.html

# File lib/fog/aws/requests/storage/put_object_acl.rb, line 30
def put_object_acl(bucket_name, object_name, acl, options = {})
  query = {'acl' => nil}
  if version_id = options.delete('versionId')
    query['versionId'] = version_id
  end

  data = ""
  headers = {}

  if acl.is_a?(Hash)
    data = Fog::AWS::Storage.hash_to_acl(acl)
  else
    if !['private', 'public-read', 'public-read-write', 'authenticated-read'].include?(acl)
      raise Excon::Errors::BadRequest.new('invalid x-amz-acl')
    end
    headers['x-amz-acl'] = acl
  end

  headers['Content-MD5'] = Base64.encode64(OpenSSL::Digest::MD5.digest(data)).strip
  headers['Content-Type'] = 'application/json'
  headers['Date'] = Fog::Time.now.to_date_header

  request({
    :body     => data,
    :expects  => 200,
    :headers  => headers,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :method   => 'PUT',
    :query    => query
  })
end
put_object_tagging(bucket_name, object_name, tags) click to toggle source

Change tag set for an S3 object

@param bucket_name [String] Name of bucket to modify object in @param object_name [String] Name of object to modify

@param tags [Hash]:

* Key [String]: tag key
* Value [String]: tag value

@see docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html

# File lib/fog/aws/requests/storage/put_object_tagging.rb, line 16
        def put_object_tagging(bucket_name, object_name, tags)
          tagging = tags.map do |k,v|
            "<Tag><Key>#{k}</Key><Value>#{v}</Value></Tag>"
          end.join("\n")
          data =
              <<-DATA
<Tagging xmlns="http://doc.s3.amazonaws.com/2006-03-01" >
  <TagSet>
    #{tagging}
  </TagSet>
</Tagging>
          DATA

          request({
            :body     => data,
            :expects  => 200,
            :headers  => {'Content-MD5' => Base64.encode64(OpenSSL::Digest::MD5.digest(data)).chomp!, 'Content-Type' => 'application/xml'},
            :bucket_name => bucket_name,
            :object_name => object_name,
            :method   => 'PUT',
            :query    => {'tagging' => nil}
          })
        end
put_request_payment(bucket_name, payer) click to toggle source

Change who pays for requests to an S3 bucket

@param bucket_name [String] name of bucket to modify @param payer [String] valid values are BucketOwner or Requester

@see docs.amazonwebservices.com/AmazonS3/latest/API/RESTrequestPaymentPUT.html

# File lib/fog/aws/requests/storage/put_request_payment.rb, line 12
        def put_request_payment(bucket_name, payer)
          data =
<<-DATA
<RequestPaymentConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Payer>#{payer}</Payer>
</RequestPaymentConfiguration>
DATA
          request({
            :body     => data,
            :expects  => 200,
            :headers  => {},
            :bucket_name => bucket_name,
            :method   => 'PUT',
            :query    => {'requestPayment' => nil}
          })
        end
reload() click to toggle source
# File lib/fog/aws/storage.rb, line 574
def reload
  @connection.reset if @connection
end
sync_clock() click to toggle source

Sync clock against S3 to avoid skew errors

# File lib/fog/aws/requests/storage/sync_clock.rb, line 7
def sync_clock
  response = begin
    get_service
  rescue Excon::Errors::HTTPStatusError => error
    error.response
  end
  Fog::Time.now = Time.parse(response.headers['Date'])
end
upload_part(bucket_name, object_name, upload_id, part_number, data, options = {}) click to toggle source

Upload a part for a multipart upload

@param bucket_name [String] Name of bucket to add part to @param object_name [String] Name of object to add part to @param upload_id [String] Id of upload to add part to @param part_number [String] Index of part in upload @param data [File||String] Content for part @param options [Hash] @option options Content-MD5 [String] Base64 encoded 128-bit MD5 digest of message

@return [Excon::Response] response

* headers [Hash]:
  * ETag [String] etag of new object (will be needed to complete upload)

@see docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html

# File lib/fog/aws/requests/storage/upload_part.rb, line 21
def upload_part(bucket_name, object_name, upload_id, part_number, data, options = {})
  data = Fog::Storage.parse_data(data)
  headers = options
  headers['Content-Length'] = data[:headers]['Content-Length']
  request({
    :body       => data[:body],
    :expects    => 200,
    :idempotent => true,
    :headers    => headers,
    :bucket_name => bucket_name,
    :object_name => object_name,
    :method     => 'PUT',
    :query      => {'uploadId' => upload_id, 'partNumber' => part_number}
  })
end
upload_part_copy(target_bucket_name, target_object_name, upload_id, part_number, options = {}) click to toggle source

Upload a part for a multipart copy

@param target_bucket_name [String] Name of bucket to create copy in @param target_object_name [String] Name for new copy of object @param upload_id [String] Id of upload to add part to @param part_number [String] Index of part in upload @param options [Hash]: @option options [String] x-amz-metadata-directive Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE'] @option options [String] x-amz-copy_source-if-match Copies object if its etag matches this value @option options [Time] x-amz-copy_source-if-modified_since Copies object it it has been modified since this time @option options [String] x-amz-copy_source-if-none-match Copies object if its etag does not match this value @option options [Time] x-amz-copy_source-if-unmodified-since Copies object it it has not been modified since this time @option options [Time] x-amz-copy-source-range Specifes the range of bytes to copy from the source object

@return [Excon::Response]

* body [Hash]:
  * ETag [String] - etag of new object
  * LastModified [Time] - date object was last modified

@see docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html

# File lib/fog/aws/requests/storage/upload_part_copy.rb, line 47
def upload_part_copy(target_bucket_name, target_object_name, upload_id, part_number, options = {})
  headers = options
  request({
    :expects    => 200,
    :idempotent => true,
    :headers    => headers,
    :bucket_name => target_bucket_name,
    :object_name => target_object_name,
    :method     => 'PUT',
    :query      => {'uploadId' => upload_id, 'partNumber' => part_number},
    :parser   => Fog::Parsers::AWS::Storage::UploadPartCopyObject.new,
  })
end

Private Instance Methods

_request(scheme, host, port, params, original_params, &block) click to toggle source
# File lib/fog/aws/storage.rb, line 671
def _request(scheme, host, port, params, original_params, &block)
  connection(scheme, host, port).request(params, &block)
rescue Excon::Errors::MovedPermanently, Excon::Errors::TemporaryRedirect => error
  headers = (error.response.is_a?(Hash) ? error.response[:headers] : error.response.headers)
  new_params = {}
  if headers.has_key?('Location')
    new_params[:host] = URI.parse(headers['Location']).host
  else
    body = error.response.is_a?(Hash) ? error.response[:body] : error.response.body
    # some errors provide info indirectly
    new_params[:bucket_name] =  %r{<Bucket>([^<]*)</Bucket>}.match(body).captures.first
    new_params[:host] = %r{<Endpoint>([^<]*)</Endpoint>}.match(body).captures.first
    # some errors provide it directly
    @new_region = %r{<Region>([^<]*)</Region>}.match(body) ? Regexp.last_match.captures.first : nil
  end
  Fog::Logger.warning("fog: followed redirect to #{host}, connecting to the matching region will be more performant")
  original_region, original_signer = @region, @signer
  @region = @new_region || case new_params[:host]
  when /s3.amazonaws.com/, /s3-external-1.amazonaws.com/
    DEFAULT_REGION
  else
    %r{s3[\.\-]([^\.]*).amazonaws.com}.match(new_params[:host]).captures.first
  end
  if @signature_version == 4
    @signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 's3')
    original_params[:headers].delete('Authorization')
  end
  response = request(original_params.merge(new_params), &block)
  @region, @signer = original_region, original_signer
  response
end
connection(scheme, host, port) click to toggle source
# File lib/fog/aws/storage.rb, line 596
def connection(scheme, host, port)
  uri = "#{scheme}://#{host}:#{port}"
  if @persistent
    unless uri == @connection_uri
      @connection_uri = uri
      reload
      @connection = nil
    end
  else
    @connection = nil
  end
  @connection ||= Fog::XML::Connection.new(uri, @persistent, @connection_options)
end
request(params, &block) click to toggle source
# File lib/fog/aws/storage.rb, line 610
def request(params, &block)
  refresh_credentials_if_expired

  date = Fog::Time.now

  params = params.dup
  stringify_query_keys(params)
  params[:headers] = (params[:headers] || {}).dup

  params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token

  if @signature_version == 2
    expires = date.to_date_header
    params[:headers]['Date'] = expires
    params[:headers]['Authorization'] = "AWS #{@aws_access_key_id}:#{signature_v2(params, expires)}"
  end

  params = request_params(params)
  scheme = params.delete(:scheme)
  host   = params.delete(:host)
  port   = params.delete(:port) || DEFAULT_SCHEME_PORT[scheme]
  params[:headers]['Host'] = host


  if @signature_version == 4
    params[:headers]['x-amz-date'] = date.to_iso8601_basic
    if params[:body].respond_to?(:read)
      if @enable_signature_v4_streaming
        # See http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html
        # We ignore the bit about setting the content-encoding to aws-chunked because
        # this can cause s3 to serve files with a blank content encoding which causes problems with some CDNs
        # AWS have confirmed that s3 can infer that the content-encoding is aws-chunked from the x-amz-content-sha256 header
        #
        params[:headers]['x-amz-content-sha256'] = 'STREAMING-AWS4-HMAC-SHA256-PAYLOAD'
        params[:headers]['x-amz-decoded-content-length'] = params[:headers].delete 'Content-Length'
      else
        params[:headers]['x-amz-content-sha256'] = 'UNSIGNED-PAYLOAD'
      end
    else
      params[:headers]['x-amz-content-sha256'] ||= OpenSSL::Digest::SHA256.hexdigest(params[:body] || '')
    end
    signature_components = @signer.signature_components(params, date, params[:headers]['x-amz-content-sha256'])
    params[:headers]['Authorization'] = @signer.components_to_header(signature_components)

    if params[:body].respond_to?(:read) && @enable_signature_v4_streaming
      body = params.delete :body
      params[:request_block] = S3Streamer.new(body, signature_components['X-Amz-Signature'], @signer, date)
    end
  end
  # FIXME: ToHashParser should make this not needed
  original_params = params.dup

  if @instrumentor
    @instrumentor.instrument("#{@instrumentor_name}.request", params) do
      _request(scheme, host, port, params, original_params, &block)
    end
  else
      _request(scheme, host, port, params, original_params, &block)
  end
end
setup_credentials(options) click to toggle source
# File lib/fog/aws/storage.rb, line 581
def setup_credentials(options)
  @aws_credentials_refresh_threshold_seconds = options[:aws_credentials_refresh_threshold_seconds]

  @aws_access_key_id     = options[:aws_access_key_id]
  @aws_secret_access_key = options[:aws_secret_access_key]
  @aws_session_token     = options[:aws_session_token]
  @aws_credentials_expire_at = options[:aws_credentials_expire_at]

  if @signature_version == 4
    @signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 's3')
  elsif @signature_version == 2
    @hmac = Fog::HMAC.new('sha1', @aws_secret_access_key)
  end
end
signature_v2(params, expires) click to toggle source
# File lib/fog/aws/storage.rb, line 764
        def signature_v2(params, expires)
          headers = params[:headers] || {}

          string_to_sign =
<<-DATA
#{params[:method].to_s.upcase}
#{headers['Content-MD5']}
#{headers['Content-Type']}
#{expires}
DATA

          amz_headers, canonical_amz_headers = {}, ''
          for key, value in headers
            if key[0..5] == 'x-amz-'
              amz_headers[key] = value
            end
          end
          amz_headers = amz_headers.sort {|x, y| x[0] <=> y[0]}
          for key, value in amz_headers
            canonical_amz_headers << "#{key}:#{value}\n"
          end
          string_to_sign << canonical_amz_headers

          query_string = ''
          if params[:query]
            query_args = []
            for key in params[:query].keys.sort
              if VALID_QUERY_KEYS.include?(key)
                value = params[:query][key]
                if value
                  query_args << "#{key}=#{value}"
                else
                  query_args << key
                end
              end
            end
            if query_args.any?
              query_string = '?' + query_args.join('&')
            end
          end

          canonical_path = (params[:path] || object_to_path(params[:object_name])).to_s
          canonical_path = '/' + canonical_path if canonical_path[0..0] != '/'

          if params[:bucket_name]
            canonical_resource = "/#{params[:bucket_name]}#{canonical_path}"
          else
            canonical_resource = canonical_path
          end
          canonical_resource << query_string
          string_to_sign << canonical_resource
          signed_string = @hmac.sign(string_to_sign)
          Base64.encode64(signed_string).chomp!
        end
stringify_query_keys(params) click to toggle source
# File lib/fog/aws/storage.rb, line 819
def stringify_query_keys(params)
  params[:query] = Hash[params[:query].map { |k,v| [k.to_s, v] }] if params[:query]
end