about summary refs log tree commit homepage
path: root/lib/yahns/openssl_client.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yahns/openssl_client.rb')
-rw-r--r--lib/yahns/openssl_client.rb52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/yahns/openssl_client.rb b/lib/yahns/openssl_client.rb
new file mode 100644
index 0000000..e4e76c9
--- /dev/null
+++ b/lib/yahns/openssl_client.rb
@@ -0,0 +1,52 @@
+# Copyright (C) 2014, all contributors <yahns-public@yhbt.net>
+# License: GPLv3 or later (see COPYING for details)
+
+require_relative 'sendfile_compat'
+
+# this is to be included into a Kgio::Socket-derived class
+# this requires Ruby 2.1 and later for "exception: false"
+module Yahns::OpenSSLClient # :nodoc:
+  include Yahns::SendfileCompat
+
+  def yahns_init_ssl(ssl_ctx)
+    @need_accept = true
+    @ssl = OpenSSL::SSL::SSLSocket.new(self, ssl_ctx)
+  end
+
+  def kgio_trywrite(buf)
+    rv = @ssl.write_nonblock(buf, exception: false)
+    Integer === rv and
+      rv = buf.bytesize == rv ? nil : buf.byteslice(rv, buf.bytesize)
+    rv
+  end
+
+  def kgio_syssend(buf, flags)
+    kgio_trywrite(buf)
+  end
+
+  def kgio_tryread(len, buf)
+    if @need_accept
+      # most protocols require read before write, so we start the negotiation
+      # process here:
+      begin
+        @ssl.accept_nonblock
+      rescue IO::WaitReadable
+        return :wait_readable
+      rescue IO::WaitWritable
+        return :wait_writable
+      end
+      @need_accept = false
+    end
+    @ssl.read_nonblock(len, buf, exception: false)
+  end
+
+  def shutdown(*args)
+    @ssl.shutdown(*args)
+    super # BasicSocket#shutdown
+  end
+
+  def close
+    @ssl.close
+    super # IO#close
+  end
+end