1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
# frozen_string_literal: true
require 'openssl'
module Aws
module Plugins
# @api private
class HttpChecksum < Seahorse::Client::Plugin
# @api private
class Handler < Seahorse::Client::Handler
CHUNK_SIZE = 1 * 1024 * 1024 # one MB
def call(context)
if context.operation.http_checksum_required
body = context.http_request.body
context.http_request.headers['Content-Md5'] ||= md5(body)
end
@handler.call(context)
end
private
# @param [File, Tempfile, IO#read, String] value
# @return [String<MD5>]
def md5(value)
if (value.is_a?(File) || value.is_a?(Tempfile)) &&
!value.path.nil? && File.exist?(value.path)
OpenSSL::Digest::MD5.file(value).base64digest
elsif value.respond_to?(:read)
md5 = OpenSSL::Digest::MD5.new
update_in_chunks(md5, value)
md5.base64digest
else
OpenSSL::Digest::MD5.digest(value).base64digest
end
end
def update_in_chunks(digest, io)
loop do
chunk = io.read(CHUNK_SIZE)
break unless chunk
digest.update(chunk)
end
io.rewind
end
end
def add_handlers(handlers, _config)
# priority set low to ensure checksum is computed AFTER the request is
# built but before it is signed
handlers.add(Handler, priority: 10, step: :build)
end
end
end
end
|