class AWS::S3::CipherIO

@api private

Attributes

cipher[R]

Public Class Methods

new(cipher, stream, stream_size = nil) click to toggle source
# File lib/aws/s3/cipher_io.rb, line 20
def initialize cipher, stream, stream_size = nil

  @stream = stream
  @stream_size = stream_size
  @orig_cipher = cipher.clone

  reset_cipher

  # add a #rewind method if the original stream can be rewound
  if @stream.respond_to?(:rewind)
    Core::MetaUtils.extend_method(self, :rewind) do
      reset_cipher
      @stream.rewind
    end
  end

  # add a #size method if the stream size is known
  if stream_size
    Core::MetaUtils.extend_method(self, :size) do
      EncryptionUtils.get_encrypted_size(@stream_size)
    end
  end

end

Public Instance Methods

eof?() click to toggle source

@return [Boolean] Returns ‘true` when the entire stream has been read.

# File lib/aws/s3/cipher_io.rb, line 57
def eof?
  @eof
end
read(bytes = nil, output_buffer = nil) click to toggle source

@return [String] Returns the requested number of bytes. If no byte

amount is given, it will return the entire body of encrypted data
# File lib/aws/s3/cipher_io.rb, line 47
def read bytes = nil, output_buffer = nil
  data = if bytes
    (@eof) ? nil : read_chunk(bytes)
  else
    (@eof) ? ""  : read_all
  end
  output_buffer ? output_buffer.replace(data || '') : data
end

Private Instance Methods

handle_finish(bytes, chunk) click to toggle source

Figures out how much of the final block goes into the current chunk

and adds it.

@return [String] Returns the encrypted chunk with possible padding.

# File lib/aws/s3/cipher_io.rb, line 105
def handle_finish(bytes, chunk)
  free_space = bytes - chunk.size

  if free_space > 0
    @final = cipher.final
    chunk << @final[0..free_space-1]
    @final = @final[free_space..@final.size-1]
    @eof   = true unless @final and @final.size > 0
  end

  chunk
end
read_all() click to toggle source

@return [String] Returns the entire encrypted data

# File lib/aws/s3/cipher_io.rb, line 95
def read_all
  @eof = true
  body = @stream.read()
  data = (body and body.length > 0) ? cipher.update(body) : ""
  data << cipher.final
end
read_chunk(bytes) click to toggle source

@return [String] Returns an encrytped chunk

# File lib/aws/s3/cipher_io.rb, line 74
def read_chunk bytes
  unless @final
    # If given a number of bytes, read it out and work out encryption
    #  issues
    chunk = @stream.read(bytes)

    # If there is nothing, finish the encryption
    if chunk and chunk.length > 0
      handle_finish(bytes, cipher.update(chunk))
    else
      @eof = true
      cipher.final
    end
    # Read as much as possible if not given a byte size
  else
    @eof = true
    @final
  end
end
reset_cipher() click to toggle source

Sets the CipherIO in a reset state without having to know anything

about the cipher
# File lib/aws/s3/cipher_io.rb, line 67
def reset_cipher
  @cipher = @orig_cipher.clone
  @eof    = false
  @final  = nil
end