OpenSSL::Buffering
模块 OpenSSL :: Buffering
包含的模块:Enumerable
OpenSSL IO 缓冲混合模块。
该模块允许 OpenSSL :: SSL :: SSLSocket 表现得像 IO 一样。
你通常不会直接使用这个模块,你可以看到它在 OpenSSL :: SSL :: SSLSocket 中实现。
常量
BLOCK_SIZE
从缓冲区操作中读取或写入 SSLSocket 的默认大小。
属性
syncRW
SSLSocket 的“同步模式”。
有关全部细节,请参见 IO# 同步。
公共类方法
new(*) 显示源
创建一个 OpenSSL 缓冲 IO 模块的实例。
调用超类方法
# File ext/openssl/lib/openssl/buffering.rb, line 38
def initialize(*)
super
@eof = false
@rbuffer = ""
@sync = @io.sync
end
公共实例方法
<<(s)显示源
写入s
流。s
将使用 String#to_s
转换为字符串。
# File ext/openssl/lib/openssl/buffering.rb, line 391
def <<(s)
do_write(s)
self
end
close() 显示源
关闭 SSLSocket 并刷新所有未写入的数据。
# File ext/openssl/lib/openssl/buffering.rb, line 454
def close
flush rescue nil
sysclose
end
each(eol=$/) { |line| ... }显示源文件
执行流所在行中每行的eol
分隔符的块。
另请参阅获取
# File ext/openssl/lib/openssl/buffering.rb, line 225
def each(eol=$/)
while line = self.gets(eol)
yield line
end
end
另外别名为:each_line
each_byte(){| byte | ...} 显示源文件
为流中的每个字节调用一次给定的块。
# File ext/openssl/lib/openssl/buffering.rb, line 266
def each_byte # :yields: byte
while c = getc
yield(c.ord)
end
end
each_line(eol=$/)
别名:每个 (each)
eof()
别名为:eof?
eof?()显示源
如果流在文件中,则返回 true,这意味着不再有数据要读取。
# File ext/openssl/lib/openssl/buffering.rb, line 297
def eof?
fill_rbuff if !@eof && @rbuffer.empty?
@eof && @rbuffer.empty?
end
还有别名:eof
flush()显示源文件
将缓存的数据刷新到 SSLSocket。
# File ext/openssl/lib/openssl/buffering.rb, line 442
def flush
osync = @sync
@sync = true
do_write ""
return self
ensure
@sync = osync
end
getc()显示源文件
从流中读取一个字符。如果在文件结尾处调用,则返回 nil。
# File ext/openssl/lib/openssl/buffering.rb, line 259
def getc
read(1)
end
gets(eol=$/, limit=nil) 显示源代码
从流中读取下一个“行”。行被eol
分隔。如果limit
提供,结果不会超过给定的字节数。
eol
可能是一个字符串或正则表达式。
不像 IO#获取行读取不会被分配到+ $ _ +。
与 IO#不同,如果提供了限制,则必须提供分隔符。
# File ext/openssl/lib/openssl/buffering.rb, line 201
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 size && limit && limit >= 0
size = [size, limit].min
end
consume_rbuff(size)
end
print(*args) 显示源文件
写入args
流。
查看 IO#print 了解完整的细节。
# File ext/openssl/lib/openssl/buffering.rb, line 421
def print(*args)
s = ""
args.each{ |arg| s << arg.to_s }
do_write(s)
nil
end
printf(s,* args)显示源文件
在格式字符串的控制下格式化并写入流转换参数。
有关格式字符串详细信息,请参阅内核#sprintf。
# File ext/openssl/lib/openssl/buffering.rb, line 434
def printf(s, *args)
do_write(s % args)
nil
end
puts(* args)显示源文件
args
与记录分隔符一起写入流。
请参阅 IO# 提供详细信息。
# File ext/openssl/lib/openssl/buffering.rb, line 401
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) 显示源文件
从流中读取size
字节。如果buf
提供,它必须引用将接收数据的字符串。
请参阅 IO#以了解完整的详细信息。
# File ext/openssl/lib/openssl/buffering.rb, line 85
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
read_nonblock(maxlen,buf = nil,例外:true)显示源文件
以maxlen
非阻塞方式读取大多数字节。
当没有数据可以被阻塞读取时,会引发由 IO :: WaitReadable 或 IO :: WaitWritable 扩展的 OpenSSL :: SSL :: SSLError。
IO :: WaitReadable 意味着 SSL 需要在内部读取,因此应当在底层 IO 可读时再次调用 #read_nonblock。
IO :: WaitWritable 表示 SSL 需要在内部写入,因此应在基础 IO 可写后再次调用 #read_nonblock。
#read_nonblock 需要两个 rescue 子句,如下所示:
# 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
请注意,#read_nonblock 写入底层 IO 的一个原因是当对等方请求新的 TLS / SSL 握手时。有关更多详细信息,请参阅 openssl FAQ。
通过指定关键字参数异常
来false
,你可以指出 #read_nonblock应该不会引发 IO :: 等待*能例外,但返回符号:wait_writable
或:wait_readable
代替。在 EOF 中,它将返回nil
而不是引发 EOFError。
# File ext/openssl/lib/openssl/buffering.rb, line 170
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
ret
end
readchar()显示源文件
从流中读取一个字符的字符串。在文件结尾处引发 EOFError。
# File ext/openssl/lib/openssl/buffering.rb, line 276
def readchar
raise EOFError if eof?
getc
end
readline(eol = $ /)显示源文件
从分隔的eol
流中读取一行。
如果在文件结尾处引发 EOFError。
# File ext/openssl/lib/openssl/buffering.rb, line 250
def readline(eol=$/)
raise EOFError if eof?
gets(eol)
end
readlines(eol = $ /)显示源文件
从分隔的eol
流中读取行。
另请参阅获取
# File ext/openssl/lib/openssl/buffering.rb, line 237
def readlines(eol=$/)
ary = []
while line = self.gets(eol)
ary << line
end
ary
end
readpartial(maxlen,buf = nil)显示源文件
从流中读取大多数maxlen
从流中读取大多数字节。如果buf
提供,它必须引用将接收数据的字符串。
有关完整的详细信息,请参阅 IO#readpartial。
# File ext/openssl/lib/openssl/buffering.rb, line 112
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
ret
end
ungetc(c)显示源文件
将字符推c
回到流中,以便后续的缓存字符读取将返回该字符。
与 IO#getc 不同,多个字节可能会被推回到流中。
对未缓冲的读取(例如 sysread)没有影响。
# File ext/openssl/lib/openssl/buffering.rb, line 289
def ungetc(c)
@rbuffer[0,0] = c.chr
end
write(s) 显示源
写入s
流。如果参数不是字符串,它将使用 String#to_s
进行转换。返回写入的字节数。
# File ext/openssl/lib/openssl/buffering.rb, line 340
def write(s)
do_write(s)
s.bytesize
end
write_nonblock(s,例外:true)显示源文件
s
以非阻塞的方式写入。
如果存在缓冲数据,则首先进行刷新。这可能会阻止。
#write_nonblock 返回写入 SSL 连接的字节数。
当没有数据可以被写入没有阻塞时,会引发由 IO :: WaitReadable或 IO :: WaitWritable 扩展的 OpenSSL :: SSL :: SSLError。
IO :: WaitReadable 意味着 SSL 需要在内部读取,因此应在基础 IO 可读后再次调用 #write_nonblock。
IO :: WaitWritable 表示 SSL 需要在内部写入,因此应在基础 IO 可写之后再次调用 #write_nonblock。
所以 #write_nonblock 需要两个 rescue 子句,如下所示。
# 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
请注意,#write_nonblock 从基础 IO 读取的一个原因是当对等方请求新的 TLS / SSL 握手时。有关更多详细信息,请参阅 openssl FAQ。
通过指定关键字参数异常
来false
,你可以指出 #write_nonblock 应该不会引发IO ::等待*能例外,但返回符号:wait_writable
或:wait_readable
代替。
# File ext/openssl/lib/openssl/buffering.rb, line 382
def write_nonblock(s, exception: true)
flush
syswrite_nonblock(s, exception: exception)
end
私有实例方法
consume_rbuff(size = nil)显示源文件
消耗size
字节从缓冲
# File ext/openssl/lib/openssl/buffering.rb, line 66
def consume_rbuff(size=nil)
if @rbuffer.empty?
nil
else
size = @rbuffer.size unless size
ret = @rbuffer[0, size]
@rbuffer[0, size] = ""
ret
end
end
do_write(s)显示源
写入s
缓冲区。当缓冲区已满或同步为真时,缓冲区将刷新到底层套接字。
# File ext/openssl/lib/openssl/buffering.rb, line 312
def do_write(s)
@wbuffer = "" unless defined? @wbuffer
@wbuffer << s
@wbuffer.force_encoding(Encoding::BINARY)
@sync ||= false
if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
remain = idx ? idx + $/.size : @wbuffer.length
nwritten = 0
while remain > 0
str = @wbuffer[nwritten,remain]
begin
nwrote = syswrite(str)
rescue Errno::EAGAIN
retry
end
remain -= nwrote
nwritten += nwrote
end
@wbuffer[0,nwritten] = ""
end
end
fill_rbuff()显示源文件
从底层 SSLSocket 填充缓冲区
# File ext/openssl/lib/openssl/buffering.rb, line 53
def fill_rbuff
begin
@rbuffer << self.sysread(BLOCK_SIZE)
rescue Errno::EAGAIN
retry
rescue EOFError
@eof = true
end
end