Module: Yahns::OpenSSLClient
- Defined in:
- lib/yahns/openssl_client.rb
Overview
this is to be included into a Kgio::Socket-derived class this requires Ruby 2.1 and later for “exception: false”
Class Method Summary collapse
-
.included(cls) ⇒ Object
:nodoc:.
Instance Method Summary collapse
- #accept_nonblock(ssl) ⇒ Object
- #close ⇒ Object
- #kgio_syssend(buf, flags) ⇒ Object
- #kgio_tryread(len, buf) ⇒ Object
- #kgio_trywrite(buf) ⇒ Object
- #kgio_trywritev(buf) ⇒ Object
-
#shutdown ⇒ Object
we never call this with a how=SHUT_* arg.
-
#sync ⇒ Object
this is special, called during IO initialization in Ruby.
- #trysendio(io, offset, count) ⇒ Object (also: #trysendfile)
- #yahns_init_ssl(ssl_ctx) ⇒ Object
Class Method Details
.included(cls) ⇒ Object
:nodoc:
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/yahns/openssl_client.rb', line 9 def self.included(cls) # Forward these methods to OpenSSL::SSL::SSLSocket so hijackers # can rely on stdlib methods instead of ugly kgio stuff that # we hope to phase out. # This is a bit weird, since OpenSSL::SSL::SSLSocket wraps # our actual socket, too, so we must take care to not blindly # use method_missing and cause infinite recursion %w(sync= read write readpartial write_nonblock read_nonblock print printf puts gets readlines readline getc readchar ungetc eof eof? << flush sysread syswrite).map!(&:to_sym).each do |m| cls.__send__(:define_method, m) { |*a| @ssl.__send__(m, *a) } end # block captures, ugh, but nobody really uses them %w(each each_line each_byte).map!(&:to_sym).each do |m| cls.__send__(:define_method, m) { |*a, &b| @ssl.__send__(m, *a, &b) } end end |
Instance Method Details
#accept_nonblock(ssl) ⇒ Object
130 131 132 |
# File 'lib/yahns/openssl_client.rb', line 130 def accept_nonblock(ssl) ssl.accept_nonblock(exception: false) end |
#close ⇒ Object
124 125 126 127 |
# File 'lib/yahns/openssl_client.rb', line 124 def close @ssl.close # flushes SSLSocket super # IO#close end |
#kgio_syssend(buf, flags) ⇒ Object
74 75 76 |
# File 'lib/yahns/openssl_client.rb', line 74 def kgio_syssend(buf, flags) kgio_trywrite(buf) end |
#kgio_tryread(len, buf) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/yahns/openssl_client.rb', line 78 def kgio_tryread(len, buf) if @need_accept # most protocols require read before write, so we start the negotiation # process here: case rv = accept_nonblock(@ssl) when :wait_readable, :wait_writable, nil return rv end @need_accept = false end @ssl.read_nonblock(len, buf, exception: false) end |
#kgio_trywrite(buf) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/yahns/openssl_client.rb', line 40 def kgio_trywrite(buf) len = buf.bytesize return if len == 0 case @ssl_blocked when nil # likely buf = @ssl_blocked = buf.dup when Exception raise @ssl_blocked when String if @ssl_blocked != buf pfx = object_id warn("#{pfx} BUG: ssl_blocked != buf\n" \ "#{pfx} ssl_blocked=#{@ssl_blocked.inspect}\n" \ "#{pfx} buf=#{buf.inspect}\n") raise 'BUG: ssl_blocked} != buf' end end case rv = @ssl.write_nonblock(buf, exception: false) when :wait_readable, :wait_writable rv # do not clear ssl_blocked when Integer @ssl_blocked = len == rv ? nil : buf.byteslice(rv, len - rv) end rescue SystemCallError => e # ECONNRESET/EPIPE e.set_backtrace([]) raise(@ssl_blocked = e) end |
#kgio_trywritev(buf) ⇒ Object
70 71 72 |
# File 'lib/yahns/openssl_client.rb', line 70 def kgio_trywritev(buf) kgio_trywrite(buf.join) end |
#shutdown ⇒ Object
we never call this with a how=SHUT_* arg
118 119 120 |
# File 'lib/yahns/openssl_client.rb', line 118 def shutdown # we never call this with a how=SHUT_* arg @ssl.sysclose end |
#sync ⇒ Object
this is special, called during IO initialization in Ruby
30 31 32 |
# File 'lib/yahns/openssl_client.rb', line 30 def sync defined?(@ssl) ? @ssl.sync : super end |
#trysendio(io, offset, count) ⇒ Object Also known as: trysendfile
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/yahns/openssl_client.rb', line 91 def trysendio(io, offset, count) return 0 if count == 0 case buf = @ssl_blocked when nil buf = do_pread(io, count, offset) or return # nil for EOF buf = @ssl_blocked = buf.dup when Exception raise buf # when String # just use it as-is end # call write_nonblock directly since kgio_trywrite allocates # an unnecessary string len = buf.size case rv = @ssl.write_nonblock(buf, exception: false) when :wait_readable, :wait_writable return rv # do not clear ssl_blocked when Integer @ssl_blocked = len == rv ? nil : buf.byteslice(rv, len - rv) end rv rescue SystemCallError => e # ECONNRESET/EPIPE e.set_backtrace([]) raise(@ssl_blocked = e) end |
#yahns_init_ssl(ssl_ctx) ⇒ Object
34 35 36 37 38 |
# File 'lib/yahns/openssl_client.rb', line 34 def yahns_init_ssl(ssl_ctx) @need_accept = true @ssl = OpenSSL::SSL::SSLSocket.new(self, ssl_ctx) @ssl_blocked = nil end |