Ruby 2.4
OpenSSL

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