summaryrefslogtreecommitdiff
path: root/ext/openssl
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-03-16 04:47:18 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-03-16 04:47:18 +0000
commit92946d44742ee9c48f418f6ff583b1bf35da9d1f (patch)
tree3d5da365a49add28be43ee1a0c41b5bd09f67f2f /ext/openssl
parent0777480af252b112be8250dc682b51881f701540 (diff)
de-nest the Buffering module
add RDoc for OpenSSL::Buffering git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31112 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/lib/openssl/buffering.rb236
1 files changed, 173 insertions, 63 deletions
diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb
index 3028fe5b52..a9c60fb512 100644
--- a/ext/openssl/lib/openssl/buffering.rb
+++ b/ext/openssl/lib/openssl/buffering.rb
@@ -14,10 +14,26 @@
$Id$
=end
-module OpenSSL
-module Buffering
+require 'openssl'
+
+##
+# OpenSSL IO buffering mix-in module.
+#
+# This module allows an OpenSSL::SSL::SSLSocket to behave like an IO.
+
+module OpenSSL::Buffering
include Enumerable
+
+ ##
+ # The "sync mode" of the SSLSocket.
+ #
+ # See IO#sync for full details.
+
attr_accessor :sync
+
+ ##
+ # Default size to read from or write to the SSLSocket for buffer operations.
+
BLOCK_SIZE = 1024*16
def initialize(*args)
@@ -31,6 +47,9 @@ module Buffering
#
private
+ ##
+ # Fills the buffer from the underlying SSLSocket
+
def fill_rbuff
begin
@rbuffer << self.sysread(BLOCK_SIZE)
@@ -41,6 +60,9 @@ module Buffering
end
end
+ ##
+ # Consumes +size+ bytes from the buffer
+
def consume_rbuff(size=nil)
if @rbuffer.empty?
nil
@@ -54,6 +76,12 @@ module Buffering
public
+ ##
+ # 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.
+
def read(size=nil, buf=nil)
if size == 0
if buf
@@ -75,6 +103,12 @@ module Buffering
(size && ret.empty?) ? nil : ret
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.
+
def readpartial(maxlen, buf=nil)
if maxlen == 0
if buf
@@ -100,38 +134,35 @@ module Buffering
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 after
- # underlying IO is readable.
- #
- # IO::WaitWritable means SSL needs to write internally.
- # So read_nonblock should be called again after
- # underlying IO is writable.
- #
- # So OpenSSL::Buffering#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 write to a underlying IO
- # is the peer requests a new TLS/SSL handshake.
- # See openssl FAQ for more details.
- # http://www.openssl.org/support/faq.html
+ ##
+ # 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.
+ #
+ # OpenSSL::Buffering#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. http://www.openssl.org/support/faq.html
+
def read_nonblock(maxlen, buf=nil)
if maxlen == 0
if buf
@@ -153,6 +184,17 @@ module Buffering
ret
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.
+
def gets(eol=$/, limit=nil)
idx = @rbuffer.index(eol)
until @eof
@@ -171,6 +213,12 @@ module Buffering
consume_rbuff(size)
end
+ ##
+ # Executes the block for every line in the stream where lines are separated
+ # by +eol+.
+ #
+ # See also #gets
+
def each(eol=$/)
while line = self.gets(eol)
yield line
@@ -178,6 +226,11 @@ module Buffering
end
alias each_line each
+ ##
+ # Reads lines from the stream which are separated by +eol+.
+ #
+ # See also #gets
+
def readlines(eol=$/)
ary = []
while line = self.gets(eol)
@@ -186,31 +239,59 @@ module Buffering
ary
end
+ ##
+ # Reads a line from the stream which is separated by +eol+.
+ #
+ # Raises EOFError if at end of file.
+
def readline(eol=$/)
raise EOFError if eof?
gets(eol)
end
+ ##
+ # Reads one character from the stream. Returns nil if called at end of
+ # file.
+
def getc
c = read(1)
c ? c[0] : nil
end
- def each_byte
+ ##
+ # Calls the given block once for each byte in the stream.
+
+ def each_byte # :yields: byte
while c = getc
yield(c)
end
end
+ ##
+ # Reads a one-character string from the stream. Raises an EOFError at end
+ # of file.
+
def readchar
raise EOFError if eof?
getc
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).
+
def ungetc(c)
@rbuffer[0,0] = c.chr
end
+ ##
+ # Returns true if the stream is at file which means there is no more data to
+ # be read.
+
def eof?
fill_rbuff if !@eof && @rbuffer.empty?
@eof && @rbuffer.empty?
@@ -222,6 +303,10 @@ module Buffering
#
private
+ ##
+ # Writes +s+ to the buffer. When the buffer is full or #sync is true the
+ # buffer is flushed to the underlying socket.
+
def do_write(s)
@wbuffer = "" unless defined? @wbuffer
@wbuffer << s
@@ -245,58 +330,67 @@ module Buffering
public
+ ##
+ # 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.
+
def write(s)
do_write(s)
s.length
end
- # Writes _str_ in the non-blocking manner.
+ ##
+ # Writes +str+ in the non-blocking manner.
#
- # If there are buffered data, it is flushed at first.
- # This may block.
+ # 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.
+ # 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
- # underlying IO is readable.
+ # 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.
+ # IO::WaitWritable means SSL needs to write internally so write_nonblock
+ # should be called again after underlying IO is writable.
#
# So OpenSSL::Buffering#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 read from a underlying IO
- # is the peer requests a new TLS/SSL handshake.
- # See openssl FAQ for more details.
- # http://www.openssl.org/support/faq.html
#
+ # # 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. http://www.openssl.org/support/faq.html
+
def write_nonblock(s)
flush
syswrite_nonblock(s)
end
+ ##
+ # Writes +s+ to the stream. +s+ will be converted to a String using
+ # String#to_s.
+
def << (s)
do_write(s)
self
end
+ ##
+ # Writes +args+ to the stream along with a record separator.
+ #
+ # See IO#puts for full details.
+
def puts(*args)
s = ""
if args.empty?
@@ -312,6 +406,11 @@ module Buffering
nil
end
+ ##
+ # Writes +args+ to the stream.
+ #
+ # See IO#print for full details.
+
def print(*args)
s = ""
args.each{ |arg| s << arg.to_s }
@@ -319,11 +418,20 @@ module Buffering
nil
end
+ ##
+ # Formats and writes to the stream converting parameters under control of
+ # the format string.
+ #
+ # See Kernel#sprintf for format string details.
+
def printf(s, *args)
do_write(s % args)
nil
end
+ ##
+ # Flushes buffered data to the SSLSocket.
+
def flush
osync = @sync
@sync = true
@@ -331,9 +439,11 @@ module Buffering
@sync = osync
end
+ ##
+ # Closes the SSLSocket and flushes any unwritten data.
+
def close
flush rescue nil
sysclose
end
end
-end