OpenSSL IO buffering mix-in module.
This module allows an OpenSSL::SSL::SSLSocket to behave like an IO.
You typically won't use this module directly, you can see it implemented in OpenSSL::SSL::SSLSocket.
Default size to read from or write to the SSLSocket for buffer operations.
Writes s to the stream.  s will be converted to a
String using String#to_s.
 
               # File openssl/lib/openssl/buffering.rb, line 389
def << (s)
  do_write(s)
  self
end
             
            Closes the SSLSocket and flushes any unwritten data.
 
               # File openssl/lib/openssl/buffering.rb, line 452
def close
  flush rescue nil
  sysclose
end
             
            Executes the block for every line in the stream where lines are separated
by eol.
See also gets
 
               # File openssl/lib/openssl/buffering.rb, line 227
def each(eol=$/)
  while line = self.gets(eol)
    yield line
  end
end
             
            Calls the given block once for each byte in the stream.
 
               # File openssl/lib/openssl/buffering.rb, line 268
def each_byte # :yields: byte
  while c = getc
    yield(c.ord)
  end
end
             
            Returns true if the stream is at file which means there is no more data to be read.
 
               # File openssl/lib/openssl/buffering.rb, line 299
def eof?
  fill_rbuff if !@eof && @rbuffer.empty?
  @eof && @rbuffer.empty?
end
             
            Flushes buffered data to the SSLSocket.
 
               # File openssl/lib/openssl/buffering.rb, line 440
def flush
  osync = @sync
  @sync = true
  do_write ""
  return self
ensure
  @sync = osync
end
             
            Reads one character from the stream. Returns nil if called at end of file.
 
               # File openssl/lib/openssl/buffering.rb, line 261
def getc
  read(1)
end
             
            Reads the next “line+ from the stream.  Lines are separated by
eol.  If limit is provided the result will not be
longer than the given number of bytes.
eol may be a String or Regexp.
Unlike IO#gets the line read will not be assigned to +$_+.
Unlike IO#gets the separator must be provided if a limit is provided.
 
               # File openssl/lib/openssl/buffering.rb, line 203
def gets(eol=$/, limit=nil)
  idx = @rbuffer.index(eol)
  until @eof
    break if idx
    fill_rbuff
    idx = @rbuffer.index(eol)
  end
  if eol.is_a?(Regexp)
    size = idx ? idx+$&.size : nil
  else
    size = idx ? idx+eol.size : nil
  end
  if limit and limit >= 0
    size = [size, limit].min
  end
  consume_rbuff(size)
end
             
            Writes args to the stream.
See IO#print for full details.
 
               # File openssl/lib/openssl/buffering.rb, line 419
def print(*args)
  s = ""
  args.each{ |arg| s << arg.to_s }
  do_write(s)
  nil
end
             
            Formats and writes to the stream converting parameters under control of the format string.
See Kernel#sprintf for format string details.
 
               # File openssl/lib/openssl/buffering.rb, line 432
def printf(s, *args)
  do_write(s % args)
  nil
end
             
            Writes args to the stream along with a record separator.
See IO#puts for full details.
 
               # File openssl/lib/openssl/buffering.rb, line 399
def puts(*args)
  s = ""
  if args.empty?
    s << "\n"
  end
  args.each{|arg|
    s << arg.to_s
    if $/ && /\n\z/ !~ s
      s << "\n"
    end
  }
  do_write(s)
  nil
end
             
            Reads size bytes from the stream.  If buf is
provided it must reference a string which will receive the data.
See IO#read for full details.
 
               # File openssl/lib/openssl/buffering.rb, line 90
def read(size=nil, buf=nil)
  if size == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  until @eof
    break if size && size <= @rbuffer.size
    fill_rbuff
  end
  ret = consume_rbuff(size) || ""
  if buf
    buf.replace(ret)
    ret = buf
  end
  (size && ret.empty?) ? nil : ret
end
             
            Reads at most maxlen bytes in the non-blocking manner.
When no data can be read without blocking it raises OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable.
IO::WaitReadable means SSL needs to read internally so #read_nonblock should be called again when the underlying IO is readable.
IO::WaitWritable means SSL needs to write internally so #read_nonblock should be called again after the underlying IO is writable.
#read_nonblock needs two rescue clause as follows:
# emulates blocking read (readpartial). begin result = ssl.read_nonblock(maxlen) rescue IO::WaitReadable IO.select([io]) retry rescue IO::WaitWritable IO.select(nil, [io]) retry end
Note that one reason that #read_nonblock writes to the underlying IO is when the peer requests a new TLS/SSL handshake. See openssl the FAQ for more details. www.openssl.org/support/faq.html
 
               # File openssl/lib/openssl/buffering.rb, line 171
def read_nonblock(maxlen, buf=nil, exception: true)
  if maxlen == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  if @rbuffer.empty?
    return sysread_nonblock(maxlen, buf, exception: exception)
  end
  ret = consume_rbuff(maxlen)
  if buf
    buf.replace(ret)
    ret = buf
  end
  raise EOFError if ret.empty?
  ret
end
             
            Reads a one-character string from the stream. Raises an EOFError at end of file.
 
               # File openssl/lib/openssl/buffering.rb, line 278
def readchar
  raise EOFError if eof?
  getc
end
             
            Reads a line from the stream which is separated by eol.
Raises EOFError if at end of file.
 
               # File openssl/lib/openssl/buffering.rb, line 252
def readline(eol=$/)
  raise EOFError if eof?
  gets(eol)
end
             
            Reads lines from the stream which are separated by eol.
See also gets
 
               # File openssl/lib/openssl/buffering.rb, line 239
def readlines(eol=$/)
  ary = []
  while line = self.gets(eol)
    ary << line
  end
  ary
end
             
            Reads at most maxlen bytes from the stream.  If
buf is provided it must reference a string which will receive
the data.
See IO#readpartial for full details.
 
               # File openssl/lib/openssl/buffering.rb, line 117
def readpartial(maxlen, buf=nil)
  if maxlen == 0
    if buf
      buf.clear
      return buf
    else
      return ""
    end
  end
  if @rbuffer.empty?
    begin
      return sysread(maxlen, buf)
    rescue Errno::EAGAIN
      retry
    end
  end
  ret = consume_rbuff(maxlen)
  if buf
    buf.replace(ret)
    ret = buf
  end
  raise EOFError if ret.empty?
  ret
end
             
            Pushes character c back onto the stream such that a subsequent
buffered character read will return it.
Unlike IO#getc multiple bytes may be pushed back onto the stream.
Has no effect on unbuffered reads (such as sysread).
 
               # File openssl/lib/openssl/buffering.rb, line 291
def ungetc(c)
  @rbuffer[0,0] = c.chr
end
             
            Writes s to the stream.  If the argument is not a string it
will be converted using String#to_s.  Returns the number of bytes written.
 
               # File openssl/lib/openssl/buffering.rb, line 342
def write(s)
  do_write(s)
  s.bytesize
end
             
            Writes str in the non-blocking manner.
If there is buffered data, it is flushed first. This may block.
#write_nonblock returns number of bytes written to the SSL connection.
When no data can be written without blocking it raises OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable.
IO::WaitReadable means SSL needs to read internally so #write_nonblock should be called again after the underlying IO is readable.
IO::WaitWritable means SSL needs to write internally so #write_nonblock should be called again after underlying IO is writable.
So #write_nonblock needs two rescue clause as follows.
# emulates blocking write. begin result = ssl.write_nonblock(str) rescue IO::WaitReadable IO.select([io]) retry rescue IO::WaitWritable IO.select(nil, [io]) retry end
Note that one reason that #write_nonblock reads from the underlying IO is when the peer requests a new TLS/SSL handshake. See the openssl FAQ for more details. www.openssl.org/support/faq.html
 
               # File openssl/lib/openssl/buffering.rb, line 380
def write_nonblock(s, exception: true)
  flush
  syswrite_nonblock(s, exception: exception)
end