class Fog::Storage::GoogleXML::Real

Public Class Methods

new(options = {}) click to toggle source

Initialize connection to Google Storage

Notes

options parameter must include values for :google_storage_access_key_id and :google_storage_secret_access_key in order to create a connection

Examples

google_storage = Storage.new(
  :google_storage_access_key_id => your_google_storage_access_key_id,
  :google_storage_secret_access_key => your_google_storage_secret_access_key
)

Parameters

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

Returns

  • Storage object with connection to google.

# File lib/fog/storage/google_xml/real.rb, line 24
def initialize(options = {})
  @google_storage_access_key_id = options[:google_storage_access_key_id]
  @google_storage_secret_access_key = options[:google_storage_secret_access_key]
  @connection_options = options[:connection_options] || {}
  @hmac = Fog::HMAC.new("sha1", @google_storage_secret_access_key)
  @host = options[:host] || "storage.googleapis.com"
  @persistent = options.fetch(:persistent, true)
  @port       = options[:port] || 443
  @scheme     = options[:scheme] || "https"
  @path_style = options[:path_style] || false
end

Public Instance Methods

connection(scheme, host, port) click to toggle source
# File lib/fog/storage/google_xml/real.rb, line 78
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
copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {}) click to toggle source

Copy an object from one Google Storage bucket to another

Parameters

  • source_bucket_name<~String> - Name of source bucket

  • source_object_name<~String> - Name of source object

  • target_bucket_name<~String> - Name of bucket to create copy in

  • target_object_name<~String> - Name for new copy of object

  • options<~Hash>:

    • 'x-goog-metadata-directive'<~String> - Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE']

    • 'x-goog-copy_source-if-match'<~String> - Copies object if its etag matches this value

    • 'x-goog-copy_source-if-modified_since'<~Time> - Copies object it it has been modified since this time

    • 'x-goog-copy_source-if-none-match'<~String> - Copies object if its etag does not match this value

    • 'x-goog-copy_source-if-unmodified-since'<~Time> - Copies object it it has not been modified since this time

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • 'ETag'<~String> - etag of new object

      • 'LastModified'<~Time> - date object was last modified

# File lib/fog/storage/google_xml/requests/copy_object.rb, line 25
def copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {})
  headers = { "x-goog-copy-source" => "/#{source_bucket_name}/#{source_object_name}" }.merge(options)
  request(:expects  => 200,
          :headers  => headers,
          :host     => "#{target_bucket_name}.#{@host}",
          :method   => "PUT",
          :parser   => Fog::Parsers::Storage::Google::CopyObject.new,
          :path     => Fog::Google.escape(target_object_name))
end
delete_bucket(bucket_name) click to toggle source

Delete an Google Storage bucket

Parameters

  • bucket_name<~String> - name of bucket to delete

Returns

  • response<~Excon::Response>:

    • status<~Integer> - 204

# File lib/fog/storage/google_xml/requests/delete_bucket.rb, line 13
def delete_bucket(bucket_name)
  request(:expects  => 204,
          :headers  => {},
          :host     => "#{bucket_name}.#{@host}",
          :method   => "DELETE")
end
delete_object(bucket_name, object_name) click to toggle source

Delete an object from Google Storage

Parameters

  • bucket_name<~String> - Name of bucket containing object to delete

  • object_name<~String> - Name of object to delete

Returns

  • response<~Excon::Response>:

    • status<~Integer> - 204

# File lib/fog/storage/google_xml/requests/delete_object.rb, line 14
def delete_object(bucket_name, object_name)
  request(:expects    => 204,
          :headers    => {},
          :host       => "#{bucket_name}.#{@host}",
          :idempotent => true,
          :method     => "DELETE",
          :path       => Fog::Google.escape(object_name))
end
delete_object_url(bucket_name, object_name, expires) click to toggle source

Get an expiring object url from Google Storage for deleting an object

Parameters

  • bucket_name<~String> - Name of bucket containing object

  • object_name<~String> - Name of object to get expiring url for

  • expires<~Time> - An expiry time for this url

Returns

  • response<~Excon::Response>:

    • body<~String> - url for object

# File lib/fog/storage/google_xml/requests/delete_object_url.rb, line 16
def delete_object_url(bucket_name, object_name, expires)
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  raise ArgumentError.new("object_name is required") unless object_name
  https_url({
              :headers  => {},
              :host     => @host,
              :method   => "DELETE",
              :path     => "#{bucket_name}/#{object_name}"
            }, expires)
end
get_bucket(bucket_name, options = {}) click to toggle source

List information about objects in an Google Storage bucket

Parameters

  • bucket_name<~String> - name of bucket to list object keys from

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

    • 'delimiter'<~String> - causes keys with the same string between the prefix value and the first occurence of delimiter to be rolled up

    • 'marker'<~String> - limits object keys to only those that appear lexicographically after its value.

    • 'max-keys'<~Integer> - limits number of object keys returned

    • 'prefix'<~String> - limits object keys to those beginning with its value.

Returns

  • response<~Excon::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

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

Get access control list for an Google Storage bucket

Parameters

  • bucket_name<~String> - name of bucket to get access control list for

Returns

  • response<~Excon::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]

# File lib/fog/storage/google_xml/requests/get_bucket_acl.rb, line 26
def get_bucket_acl(bucket_name)
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  request(:expects    => 200,
          :headers    => {},
          :host       => "#{bucket_name}.#{@host}",
          :idempotent => true,
          :method     => "GET",
          :parser     => Fog::Parsers::Storage::Google::AccessControlList.new,
          :query      => { "acl" => nil })
end
get_object(bucket_name, object_name, options = {}, &_block) click to toggle source

Get an object from Google Storage

Parameters

  • bucket_name<~String> - Name of bucket to read from

  • object_name<~String> - Name of object to read

  • options<~Hash>:

    • 'If-Match'<~String> - Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed).

    • 'If-Modified-Since'<~Time> - Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified).

    • 'If-None-Match'<~String> - Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified)

    • 'If-Unmodified-Since'<~Time> - Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed).

    • 'Range'<~String> - Range of object to download

    • 'versionId'<~String> - specify a particular version to retrieve

Returns

  • response<~Excon::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

# File lib/fog/storage/google_xml/requests/get_object.rb, line 27
def get_object(bucket_name, object_name, options = {}, &_block)
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  raise ArgumentError.new("object_name is required") unless object_name

  params = { :headers => {} }
  if version_id = options.delete("versionId")
    params[:query] = { "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-Modified-Since"]
    params[:headers]["If-Unmodified-Since"] = Fog::Time.at(options["If-Unmodified-Since"].to_i).to_date_header
  end

  params[:response_block] = Proc.new if block_given?

  request(params.merge!(:expects        => [200, 206],
                        :host           => "#{bucket_name}.#{@host}",
                        :idempotent     => true,
                        :method         => "GET",
                        :path           => Fog::Google.escape(object_name)))
end
get_object_acl(bucket_name, object_name, options = {}) click to toggle source

Get access control list for an Google Storage object

Parameters

  • bucket_name<~String> - name of bucket containing object

  • object_name<~String> - name of object to get access control list for

  • options<~Hash>:

    • 'versionId'<~String> - specify a particular version to retrieve

Returns

  • response<~Excon::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]

# File lib/fog/storage/google_xml/requests/get_object_acl.rb, line 29
def get_object_acl(bucket_name, object_name, options = {})
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  raise ArgumentError.new("object_name is required") unless object_name
  query = { "acl" => nil }
  if version_id = options.delete("versionId")
    query["versionId"] = version_id
  end
  request(:expects    => 200,
          :headers    => {},
          :host       => "#{bucket_name}.#{@host}",
          :idempotent => true,
          :method     => "GET",
          :parser     => Fog::Parsers::Storage::Google::AccessControlList.new,
          :path       => Fog::Google.escape(object_name),
          :query      => query)
end
get_object_url(bucket_name, object_name, expires, options = {}) click to toggle source

Get an expiring object url from Google Storage

Parameters

  • bucket_name<~String> - Name of bucket containing object

  • object_name<~String> - Name of object to get expiring url for

  • expires<~Time> - An expiry time for this url

  • options<~Hash> - A list of key-value pairs to send as query strings

Returns

  • response<~Excon::Response>:

    • body<~String> - url for object

# File lib/fog/storage/google_xml/requests/get_object_url.rb, line 17
def get_object_url(bucket_name, object_name, expires, options = {})
  Fog::Logger.deprecation("Fog::Storage::Google => #get_object_url is deprecated, use #get_object_https_url instead[/] [light_black](#{caller(1..1).first})")
  get_object_https_url(bucket_name, object_name, expires, options)
end
get_service() click to toggle source

List information about Google Storage buckets for authorized user

Returns

  • response<~Excon::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

# File lib/fog/storage/google_xml/requests/get_service.rb, line 16
def get_service
  request(:expects  => 200,
          :headers  => {},
          :host     => @host,
          :idempotent => true,
          :method   => "GET",
          :parser   => Fog::Parsers::Storage::Google::GetService.new)
end
head_object(bucket_name, object_name, options = {}) click to toggle source

Get headers for an object from Google Storage

Parameters

  • bucket_name<~String> - Name of bucket to read from

  • object_name<~String> - Name of object to read

  • options<~Hash>:

    • 'If-Match'<~String> - Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed).

    • 'If-Modified-Since'<~Time> - Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified).

    • 'If-None-Match'<~String> - Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified)

    • 'If-Unmodified-Since'<~Time> - Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed).

    • 'Range'<~String> - Range of object to download

    • 'versionId'<~String> - specify a particular version to retrieve

Returns

  • response<~Excon::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

# File lib/fog/storage/google_xml/requests/head_object.rb, line 26
def head_object(bucket_name, object_name, options = {})
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  raise ArgumentError.new("object_name is required") unless object_name
  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, 206],
          :headers    => headers,
          :host       => "#{bucket_name}.#{@host}",
          :idempotent => true,
          :method     => "HEAD",
          :path       => Fog::Google.escape(object_name),
          :query      => query)
end
put_bucket(bucket_name, options = {}) click to toggle source

Create an Google Storage bucket

Parameters

  • bucket_name<~String> - name of bucket to create

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

    • 'LocationConstraint'<~Symbol> - sets the location for the bucket

    • 'x-goog-acl'<~String> - The predefined access control list (ACL) that you want to apply to the bucket.

Returns

  • response<~Excon::Response>:

    • status<~Integer> - 200

# File lib/fog/storage/google_xml/requests/put_bucket.rb, line 16
def put_bucket(bucket_name, options = {})
  location_constraint = options.delete("LocationConstraint")
  storage_class = options.delete("StorageClass")
  if location_constraint || storage_class
    data = "<CreateBucketConfiguration>"

    data += "<LocationConstraint>#{location_constraint}</LocationConstraint>" if location_constraint
    data += "<StorageClass>#{storage_class}</StorageClass>" if storage_class
    data += "</CreateBucketConfiguration>"

  else
    data = nil
  end
  request(:expects    => 200,
          :body       => data,
          :headers    => options,
          :idempotent => true,
          :host       => "#{bucket_name}.#{@host}",
          :method     => "PUT")
end
put_bucket_acl(bucket_name, acl) click to toggle source

Change access control list for an Google Storage bucket

# File lib/fog/storage/google_xml/requests/put_bucket_acl.rb, line 14
        def put_bucket_acl(bucket_name, acl)
          data = <<-DATA
<AccessControlList>
  <Owner>
    #{tag('ID', acl['Owner']['ID'])}
  </Owner>
  <Entries>
    #{entries_list(acl['AccessControlList'])}
  </Entries>
</AccessControlList>
DATA

          request(:body     => data,
                  :expects  => 200,
                  :headers  => {},
                  :host     => "#{bucket_name}.#{@host}",
                  :method   => "PUT",
                  :query    => { "acl" => nil })
        end
put_object(bucket_name, object_name, data, options = {}) click to toggle source

Create an object in an Google Storage bucket

Parameters

  • bucket_name<~String> - Name of bucket to create object in

  • object_name<~String> - Name of object to create

  • data<~File> - File or String to create object from

  • options<~Hash>:

    • 'Cache-Control'<~String> - Caching behaviour

    • 'Content-Disposition'<~String> - Presentational information for the object

    • 'Content-Encoding'<~String> - Encoding of object data

    • 'Content-Length'<~String> - Size of object in bytes (defaults to object.read.length)

    • 'Content-MD5'<~String> - Base64 encoded 128-bit MD5 digest of message (defaults to Base64 encoded MD5 of object.read)

    • 'Content-Type'<~String> - Standard MIME type describing contents (defaults to MIME::Types.of.first)

    • 'x-goog-acl'<~String> - Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read']

    • “x-goog-meta-#{name}” - Headers to be returned with object, note total size of request without body must be less than 8 KB.

Returns

  • response<~Excon::Response>:

    • headers<~Hash>:

      • 'ETag'<~String> - etag of new object

# File lib/fog/storage/google_xml/requests/put_object.rb, line 25
def put_object(bucket_name, object_name, data, options = {})
  data = Fog::Storage.parse_data(data)
  headers = data[:headers].merge!(options)
  request(:body       => data[:body],
          :expects    => 200,
          :headers    => headers,
          :host       => "#{bucket_name}.#{@host}",
          :idempotent => true,
          :method     => "PUT",
          :path       => Fog::Google.escape(object_name))
end
put_object_acl(bucket_name, object_name, acl) click to toggle source
# File lib/fog/storage/google_xml/requests/put_object_acl.rb, line 26
        def put_object_acl(bucket_name, object_name, acl)
          headers = {}
          data = ""

          if acl.is_a?(Hash)
            data = <<-DATA
<AccessControlList>
  <Owner>
    #{tag('ID', acl['Owner']['ID'])}
  </Owner>
  <Entries>
    #{entries_list(acl['AccessControlList'])}
  </Entries>
</AccessControlList>
DATA
          elsif acl.is_a?(String) && Utils::VALID_ACLS.include?(acl)
            headers["x-goog-acl"] = acl
          else
            raise Excon::Errors::BadRequest.new("invalid x-goog-acl")
          end

          request(:body     => data,
                  :expects  => 200,
                  :headers  => headers,
                  :host     => "#{bucket_name}.#{@host}",
                  :method   => "PUT",
                  :query    => { "acl" => nil },
                  :path     => Fog::Google.escape(object_name))
        end
put_object_url(bucket_name, object_name, expires, headers = {}) click to toggle source

Get an expiring object url from Google Storage for putting an object

Parameters

  • bucket_name<~String> - Name of bucket containing object

  • object_name<~String> - Name of object to get expiring url for

  • expires<~Time> - An expiry time for this url

Returns

  • response<~Excon::Response>:

    • body<~String> - url for object

# File lib/fog/storage/google_xml/requests/put_object_url.rb, line 16
def put_object_url(bucket_name, object_name, expires, headers = {})
  raise ArgumentError.new("bucket_name is required") unless bucket_name
  raise ArgumentError.new("object_name is required") unless object_name
  https_url({
              :headers  => headers,
              :host     => @host,
              :method   => "PUT",
              :path     => "#{bucket_name}/#{object_name}"
            }, expires)
end
reload() click to toggle source
# File lib/fog/storage/google_xml/real.rb, line 36
def reload
  @connection.reset if @connection
end
signature(params) click to toggle source
# File lib/fog/storage/google_xml/real.rb, line 40
        def signature(params)
          string_to_sign = <<-DATA
#{params[:method]}
#{params[:headers]['Content-MD5']}
#{params[:headers]['Content-Type']}
#{params[:headers]['Date']}
DATA

          google_headers = {}
          canonical_google_headers = ""
          params[:headers].each do |key, value|
            google_headers[key] = value if key[0..6] == "x-goog-"
          end

          google_headers = google_headers.sort_by { |a| a[0] }
          google_headers.each do |key, value|
            canonical_google_headers << "#{key}:#{value}\n"
          end
          string_to_sign << canonical_google_headers.to_s

          canonical_resource = "/"
          if subdomain = params.delete(:subdomain)
            canonical_resource << "#{CGI.escape(subdomain).downcase}/"
          end
          canonical_resource << params[:path].to_s
          canonical_resource << "?"
          (params[:query] || {}).keys.each do |key|
            if %w(acl cors location logging requestPayment versions versioning).include?(key)
              canonical_resource << "#{key}&"
            end
          end
          canonical_resource.chop!
          string_to_sign << canonical_resource.to_s

          signed_string = @hmac.sign(string_to_sign)
          Base64.encode64(signed_string).chomp!
        end

Private Instance Methods

entries_list(access_control_list) click to toggle source
# File lib/fog/storage/google_xml/requests/put_bucket_acl.rb, line 50
def entries_list(access_control_list)
  access_control_list.map do |entry|
    tag("Entry", scope_tag(entry["Scope"]) + tag("Permission", entry["Permission"]))
  end.join("\n")
end
request(params, &block) click to toggle source
# File lib/fog/storage/google_xml/real.rb, line 94
def request(params, &block)
  params = request_params(params)
  scheme = params.delete(:scheme)
  host   = params.delete(:host)
  port   = params.delete(:port)

  params[:headers]["Date"] = Fog::Time.now.to_date_header
  params[:headers]["Authorization"] = "GOOG1 #{@google_storage_access_key_id}:#{signature(params)}"

  connection(scheme, host, port).request(params, &block)
end
scope_tag(scope) click to toggle source
# File lib/fog/storage/google_xml/requests/put_bucket_acl.rb, line 40
def scope_tag(scope)
  if %w(AllUsers AllAuthenticatedUsers).include?(scope["type"])
    "<Scope type='#{scope['type']}'/>"
  else
    "<Scope type='#{scope['type']}'>" +
      scope.to_a.reject { |pair| pair[0] == "type" }.map { |pair| tag(pair[0], pair[1]) }.join("\n") +
      "</Scope>"
  end
end
tag(name, value) click to toggle source
# File lib/fog/storage/google_xml/requests/put_bucket_acl.rb, line 36
def tag(name, value)
  "<#{name}>#{value}</#{name}>"
end