class AWS::Core::Signers::Version4::ChunkSignedStream
Constants
- CHUNK_SIGNATURE_HEADER
@api private
- CHUNK_STRING_TO_SIGN_PREFIX
@api private
- CLRF
@api private
- DEFAULT_CHUNK_SIZE
@api private
- MAX_BUFFER_SIZE
@api private
- SIGNATURE_LENGTH
@api private
Attributes
@return [Integer] the size of the final (signed) stream
Public Class Methods
@param [IO] stream The original http request body stream. @param [Integer] stream_size Size of the original stream in bytes.
This must be greater than 0.
@param [String] key The derived sigv4 signing key. @param [String] key_path The scope of the derived key. @param [String] datetime The iso8601 formatted datetime. @param [String] signature The computed signature of the request headers. @return [IO] Returns an IO-like object.
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 48 def initialize stream, stream_size, key, key_path, datetime, signature @stream = stream || StringIO.new('') @size = self.class.signed_size(stream_size) @key = key @key_path = key_path @datetime = datetime @prev_chunk_signature = signature reset end
Public Instance Methods
@param [Integer] bytes (nil) @param [String] output_buffer (nil) @return [String,nil]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 64 def read bytes = nil, output_buffer = nil data = read_bytes(bytes || @size) if output_buffer output_buffer.replace(data || '') else (data.nil? and bytes.nil?) ? '' : data end end
@return [Integer]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 74 def rewind @stream.rewind reset end
Private Instance Methods
Fills the internal buffer at least num_bytes
of data. @param
[Integer] num_bytes
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 97 def fill_buffer num_bytes while @buffer.bytesize < num_bytes && more_chunks? @buffer << next_chunk end end
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 152 def hash value OpenSSL::Digest::SHA256.new.update(value).hexdigest end
Computes the size of a header that prefixes a chunk. The size appears in the header as a string. @param [Integer] size @return [Integer]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 177 def header_length size size.to_s(16).length + CHUNK_SIGNATURE_HEADER.length + SIGNATURE_LENGTH + CLRF.length + size + CLRF.length end
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 103 def more_chunks? @more_chunks end
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 107 def next_chunk chunk = @stream.read(DEFAULT_CHUNK_SIZE) if chunk.nil? chunk = '' @more_chunks = false end sign_chunk(chunk) end
@param [String] chunk @return [String]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 133 def next_chunk_signature chunk string_to_sign = [ "AWS4-HMAC-SHA256-PAYLOAD", @datetime, @key_path, @prev_chunk_signature, hash(''), hash(chunk), ].join("\n") signature = sign(string_to_sign) @prev_chunk_signature = signature signature end
@param [Integer] num_bytes The maximum number of bytes to return. @return [String,nil] `nil` once the complete stream has been read
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 88 def read_bytes num_bytes fill_buffer(num_bytes) bytes = @buffer[0,num_bytes] @buffer = @buffer[num_bytes..-1] || '' # flatten the buffer bytes == '' ? nil : bytes end
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 81 def reset @buffer = '' @more_chunks = true end
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 147 def sign value @digest ||= OpenSSL::Digest.new('sha256') OpenSSL::HMAC.hexdigest(@digest, @key, value) end
Given a chunk of the original stream, this method returns a signed chunk with the prefixed header. @param [String] chunk @return [String]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 120 def sign_chunk chunk [ chunk.bytesize.to_s(16), CHUNK_SIGNATURE_HEADER, next_chunk_signature(chunk), CLRF, chunk, CLRF, ].join end
Computes the final size of a chunked signed stream. @param [Integer] size Size of the original, unsigned stream. @return [Integer]
# File lib/aws/core/signers/version_4/chunk_signed_stream.rb, line 161 def signed_size size full_sized_chunks = size / DEFAULT_CHUNK_SIZE trailing_bytes = size % DEFAULT_CHUNK_SIZE length = 0 length += full_sized_chunks * header_length(DEFAULT_CHUNK_SIZE) length += trailing_bytes > 0 ? header_length(trailing_bytes) : 0 length += header_length(0) length end