Method: Fog::Storage::AWS::Mock#get_object

Defined in:
lib/fog/aws/requests/storage/get_object.rb

#get_object(bucket_name, object_name, options = {}, &block) ⇒ Object

[View source]

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/fog/aws/requests/storage/get_object.rb', line 68

def get_object(bucket_name, object_name, options = {}, &block)
  version_id = options.delete('versionId')

  unless bucket_name
    raise ArgumentError.new('bucket_name is required')
  end

  unless object_name
    raise ArgumentError.new('object_name is required')
  end

  response = Excon::Response.new
  if (bucket = self.data[:buckets][bucket_name])
    object = nil
    if bucket[:objects].has_key?(object_name)
      object = version_id ? bucket[:objects][object_name].find { |object| object['VersionId'] == version_id} : bucket[:objects][object_name].first
    end

    if (object && !object[:delete_marker])
      if options['If-Match'] && options['If-Match'] != object['ETag']
        response.status = 412
      elsif options['If-Modified-Since'] && options['If-Modified-Since'] > Time.parse(object['Last-Modified'])
        response.status = 304
      elsif options['If-None-Match'] && options['If-None-Match'] == object['ETag']
        response.status = 304
      elsif options['If-Unmodified-Since'] && options['If-Unmodified-Since'] < Time.parse(object['Last-Modified'])
        response.status = 412
      else
        response.status = 200
        for key, value in object
          case key
          when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-Length', 'Content-MD5', 'Content-Type', 'ETag', 'Expires', 'Last-Modified', /^x-amz-meta-/
            response.headers[key] = value
          end
        end

        response.headers['x-amz-version-id'] = object['VersionId'] if bucket[:versioning]

        body = object[:body]
        if options['Range']
          # since AWS S3 itself does not support multiple range headers, we will use only the first
          ranges = byte_ranges(options['Range'], body.size)
          unless ranges.nil? || ranges.empty?
            response.status = 206
            body = body[ranges.first]
          end
        end

        unless block_given?
          response.body = body
        else
          data = StringIO.new(body)
          remaining = data.length
          while remaining > 0
            chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
            block.call(chunk)
            remaining -= Excon::CHUNK_SIZE
          end
        end
      end
    elsif version_id && !object
      response.status = 400
      response.body = {
        'Error' => {
          'Code' => 'InvalidArgument',
          'Message' => 'Invalid version id specified',
          'ArgumentValue' => version_id,
          'ArgumentName' => 'versionId',
          'RequestId' => Fog::Mock.random_hex(16),
          'HostId' => Fog::Mock.random_base64(65)
        }
      }

      raise(Excon::Errors.status_error({:expects => 200}, response))
    else
      response.status = 404
      response.body = "...<Code>NoSuchKey<\/Code>..."
      raise(Excon::Errors.status_error({:expects => 200}, response))
    end
  else
    response.status = 404
    response.body = "...<Code>NoSuchBucket</Code>..."
    raise(Excon::Errors.status_error({:expects => 200}, response))
  end
  response
end