class Canistor::Storage::Object
Constants
- META_HEADERS
Attributes
bucket[RW]
data[R]
key[RW]
last_modified[R]
region[RW]
Public Class Methods
new(**attributes)
click to toggle source
# File lib/canistor/storage/object.rb, line 43 def initialize(**attributes) @versioned = false @headers = {} @data = '' attributes.each do |name, value| send("#{name}=", value) end @digest = nil end
Public Instance Methods
copy()
click to toggle source
# File lib/canistor/storage/object.rb, line 136 def copy object = self.class.new(region: region, bucket: bucket, key: key) object.write(headers, data) object end
copy_headers(context)
click to toggle source
# File lib/canistor/storage/object.rb, line 146 def copy_headers(context) directive = context.http_request.headers['x-amz-metadata-directive'] case directive when 'COPY' identity_headers when 'REPLACE', nil context.http_request.headers else raise ArgumentError, "Unsupported metadata directive: `#{directive}'" end end
delete(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 142 def delete(context, subject) context.http_response.signal_headers(200, {}) end
digest()
click to toggle source
# File lib/canistor/storage/object.rb, line 80 def digest @digest ||= Digest::MD5.hexdigest(data) end
endpoint()
click to toggle source
# File lib/canistor/storage/object.rb, line 88 def endpoint Aws::Partitions::EndpointProvider.resolve(region, 's3') end
etag()
click to toggle source
# File lib/canistor/storage/object.rb, line 84 def etag '"' + digest + '"' end
get(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 123 def get(context, subject) context.http_response.signal_headers(200, headers) context.http_response.signal_data(data) end
head(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 119 def head(context, subject) context.http_response.signal_headers(200, headers) end
headers()
click to toggle source
# File lib/canistor/storage/object.rb, line 100 def headers @headers.merge(identity_headers).merge( 'date' => Time.now.httpdate, 'content-length' => size.to_s, 'last-modified' => last_modified.httpdate, 'server' => 'Canistor' ) end
identity_headers()
click to toggle source
# File lib/canistor/storage/object.rb, line 109 def identity_headers { 'etag' => etag, 'x-amz-id' => digest[0, 16], 'x-amz-id-2' => Base64.strict_encode64(digest), 'x-amz-request-id' => Base64.strict_encode64(SecureRandom.hex(16)), 'x-amz-version-id' => version_id }.compact end
label()
click to toggle source
# File lib/canistor/storage/object.rb, line 71 def label [region, bucket, key].map(&:to_s).join(':') + ' ' + headers.inspect end
location()
click to toggle source
# File lib/canistor/storage/object.rb, line 92 def location [ endpoint, bucket, key, ].join('/') end
put(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 128 def put(context, subject) if source_object = find_source(context, subject) apply_source_object(context, subject, source_object) else apply_request(context, subject) end end
size()
click to toggle source
# File lib/canistor/storage/object.rb, line 67 def size data&.size end
version_id()
click to toggle source
# File lib/canistor/storage/object.rb, line 61 def version_id if versioned? @version_id ||= generate_version_id end end
versioned=(versioned)
click to toggle source
# File lib/canistor/storage/object.rb, line 53 def versioned=(versioned) @versioned = versioned end
versioned?()
click to toggle source
# File lib/canistor/storage/object.rb, line 57 def versioned? !!@versioned end
write(headers, data)
click to toggle source
# File lib/canistor/storage/object.rb, line 75 def write(headers, data) self.headers = headers self.data = data end
Private Instance Methods
apply_request(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 177 def apply_request(context, subject) write(context.http_request.headers, context.http_request.body) context.http_response.signal_headers(200, identity_headers) end
apply_source_object(context, subject, source_object)
click to toggle source
# File lib/canistor/storage/object.rb, line 182 def apply_source_object(context, subject, source_object) write(source_object.copy_headers(context), source_object.data) CopyObjectResult.serve(context, subject, source_object, self) end
data=(data)
click to toggle source
# File lib/canistor/storage/object.rb, line 205 def data=(data) @digest = nil @last_modified = Time.now if data.respond_to?(:read) @data = data.read else @data = data end end
find_source(context, subject)
click to toggle source
# File lib/canistor/storage/object.rb, line 160 def find_source(context, subject) if source = context.http_request.headers['x-amz-copy-source'] bucket_name, key = source.split('/', 2) if bucket = Canistor.find_bucket(region, bucket_name) if object = bucket.dig(key) object else Canistor::ErrorHandler.serve_no_such_key(context, subject) throw :rendered_error end else Canistor::ErrorHandler.serve_no_such_bucket(context, subject) throw :rendered_error end end end
generate_version_id()
click to toggle source
# File lib/canistor/storage/object.rb, line 187 def generate_version_id Base64.strict_encode64(SecureRandom.hex(16)).gsub('=', '') end
headers=(headers)
click to toggle source
# File lib/canistor/storage/object.rb, line 196 def headers=(headers) return if headers.nil? headers.each do |name, value| if META_HEADERS.include?(name) || name.start_with?('x-amz-meta') @headers[name] = value end end end