Module: OpenSSL::Buffering
- Includes:
- Enumerable
- Included in:
- SSL::SSLSocket
- Defined in:
- lib/1.9/openssl/buffering.rb,
lib/1.8/openssl/buffering.rb
Overview
OpenSSL IO buffering mix-in module.
This module allows an OpenSSL::SSL::SSLSocket to behave like an IO.
Constant Summary collapse
- BLOCK_SIZE =
Default size to read from or write to the SSLSocket for buffer operations.
1024*16
Instance Attribute Summary collapse
-
#sync ⇒ Object
The “sync mode” of the SSLSocket.
Instance Method Summary collapse
-
#<<(s) ⇒ Object
Writes
s
to the stream. -
#close ⇒ Object
Closes the SSLSocket and flushes any unwritten data.
-
#each(eol = $/) ⇒ Object
(also: #each_line)
Executes the block for every line in the stream where lines are separated by
eol
. -
#each_byte ⇒ Object
Calls the given block once for each byte in the stream.
-
#eof? ⇒ Boolean
(also: #eof)
Returns true if the stream is at file which means there is no more data to be read.
-
#flush ⇒ Object
Flushes buffered data to the SSLSocket.
-
#getc ⇒ Object
Reads one character from the stream.
-
#gets(eol = $/, limit = nil) ⇒ Object
Reads the next “line+ from the stream.
- #initialize(*args) ⇒ Object
-
#print(*args) ⇒ Object
Writes
args
to the stream. -
#printf(s, *args) ⇒ Object
Formats and writes to the stream converting parameters under control of the format string.
-
#puts(*args) ⇒ Object
Writes
args
to the stream along with a record separator. -
#read(size = nil, buf = nil) ⇒ Object
Reads
size
bytes from the stream. -
#read_nonblock(maxlen, buf = nil) ⇒ Object
Reads at most
maxlen
bytes in the non-blocking manner. -
#readchar ⇒ Object
Reads a one-character string from the stream.
-
#readline(eol = $/) ⇒ Object
Reads a line from the stream which is separated by
eol
. -
#readlines(eol = $/) ⇒ Object
Reads lines from the stream which are separated by
eol
. -
#readpartial(maxlen, buf = nil) ⇒ Object
Reads at most
maxlen
bytes from the stream. -
#ungetc(c) ⇒ Object
Pushes character
c
back onto the stream such that a subsequent buffered character read will return it. -
#write(s) ⇒ Object
Writes
s
to the stream. -
#write_nonblock(s) ⇒ Object
Writes
str
in the non-blocking manner.
Instance Attribute Details
#sync ⇒ Object
The “sync mode” of the SSLSocket.
See IO#sync for full details.
30 31 32 |
# File 'lib/1.9/openssl/buffering.rb', line 30 def sync @sync end |
Instance Method Details
#<<(s) ⇒ Object
Writes s
to the stream. s
will be converted to a String using String#to_s.
381 382 383 384 |
# File 'lib/1.9/openssl/buffering.rb', line 381 def << (s) do_write(s) self end |
#close ⇒ Object
Closes the SSLSocket and flushes any unwritten data.
444 445 446 447 |
# File 'lib/1.9/openssl/buffering.rb', line 444 def close flush rescue nil sysclose end |
#each(eol = $/) ⇒ Object Also known as: each_line
Executes the block for every line in the stream where lines are separated by eol
.
See also #gets
220 221 222 223 224 |
# File 'lib/1.9/openssl/buffering.rb', line 220 def each(eol=$/) while line = self.gets(eol) yield line end end |
#each_byte ⇒ Object
Calls the given block once for each byte in the stream.
261 262 263 264 265 |
# File 'lib/1.9/openssl/buffering.rb', line 261 def each_byte while c = getc yield(c) end end |
#eof? ⇒ Boolean Also known as: eof
Returns true if the stream is at file which means there is no more data to be read.
292 293 294 295 |
# File 'lib/1.9/openssl/buffering.rb', line 292 def eof? fill_rbuff if !@eof && @rbuffer.empty? @eof && @rbuffer.empty? end |
#flush ⇒ Object
Flushes buffered data to the SSLSocket.
432 433 434 435 436 437 |
# File 'lib/1.9/openssl/buffering.rb', line 432 def flush osync = @sync @sync = true do_write "" @sync = osync end |
#getc ⇒ Object
Reads one character from the stream. Returns nil if called at end of file.
254 255 256 257 |
# File 'lib/1.9/openssl/buffering.rb', line 254 def getc c = read(1) c ? c[0] : nil end |
#gets(eol = $/, limit = nil) ⇒ Object
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.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/1.9/openssl/buffering.rb', line 196 def gets(eol=$/) 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 consume_rbuff(size) end |
#initialize(*args) ⇒ Object
23 24 25 26 27 |
# File 'lib/1.8/openssl/buffering.rb', line 23 def initialize(*args) @eof = false @rbuffer = "" @sync = @io.sync end |
#print(*args) ⇒ Object
Writes args
to the stream.
See IO#print for full details.
411 412 413 414 415 416 |
# File 'lib/1.9/openssl/buffering.rb', line 411 def print(*args) s = "" args.each{ |arg| s << arg.to_s } do_write(s) nil end |
#printf(s, *args) ⇒ Object
Formats and writes to the stream converting parameters under control of the format string.
See Kernel#sprintf for format string details.
424 425 426 427 |
# File 'lib/1.9/openssl/buffering.rb', line 424 def printf(s, *args) do_write(s % args) nil end |
#puts(*args) ⇒ Object
Writes args
to the stream along with a record separator.
See IO#puts for full details.
391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/1.9/openssl/buffering.rb', line 391 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 |
#read(size = nil, buf = nil) ⇒ Object
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.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/1.9/openssl/buffering.rb', line 83 def read(size=nil, buf=nil) if size == 0 if buf buf.clear else buf = "" end return @eof ? nil : buf 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 |
#read_nonblock(maxlen, buf = nil) ⇒ Object
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. www.openssl.org/support/faq.html
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/1.9/openssl/buffering.rb', line 164 def read_nonblock(maxlen, buf=nil) if maxlen == 0 if buf buf.clear return buf else return "" end end if @rbuffer.empty? return sysread_nonblock(maxlen, buf) end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end raise EOFError if ret.empty? ret end |
#readchar ⇒ Object
Reads a one-character string from the stream. Raises an EOFError at end of file.
271 272 273 274 |
# File 'lib/1.9/openssl/buffering.rb', line 271 def readchar raise EOFError if eof? getc end |
#readline(eol = $/) ⇒ Object
Reads a line from the stream which is separated by eol
.
Raises EOFError if at end of file.
245 246 247 248 |
# File 'lib/1.9/openssl/buffering.rb', line 245 def readline(eol=$/) raise EOFError if eof? gets(eol) end |
#readlines(eol = $/) ⇒ Object
Reads lines from the stream which are separated by eol
.
See also #gets
232 233 234 235 236 237 238 |
# File 'lib/1.9/openssl/buffering.rb', line 232 def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end |
#readpartial(maxlen, buf = nil) ⇒ Object
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.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/1.9/openssl/buffering.rb', line 110 def readpartial(maxlen, buf=nil) if maxlen == 0 if buf buf.clear else buf = "" end return @eof ? nil : buf 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 |
#ungetc(c) ⇒ Object
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).
284 285 286 |
# File 'lib/1.9/openssl/buffering.rb', line 284 def ungetc(c) @rbuffer[0,0] = c.chr end |
#write(s) ⇒ Object
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.
334 335 336 337 |
# File 'lib/1.9/openssl/buffering.rb', line 334 def write(s) do_write(s) s.length end |
#write_nonblock(s) ⇒ Object
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 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 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
372 373 374 375 |
# File 'lib/1.9/openssl/buffering.rb', line 372 def write_nonblock(s) flush syswrite_nonblock(s) end |