about summary refs log tree commit homepage
path: root/lib/yahns/openssl_client.rb
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-05-09 03:11:34 +0000
committerEric Wong <e@80x24.org>2015-05-09 03:11:34 +0000
commit89fe543e561edc740cf93b5c017d7406546382af (patch)
treea405c8b4af5ef5eccaad892d53fdcdc993f79f51 /lib/yahns/openssl_client.rb
parent055b6db8dc03fa53c0a4e738cadde4fa4342a3e5 (diff)
downloadyahns-89fe543e561edc740cf93b5c017d7406546382af.tar.gz
We do not want rack.hijack users relying on kgio_* methods since
kgio is trying to make itself obsolete (as Ruby itself adopts
kgio features).  This is a bit wonky since our common case tries
to minimize object allocation by only using the Kgio::Socket
derived class.
Diffstat (limited to 'lib/yahns/openssl_client.rb')
-rw-r--r--lib/yahns/openssl_client.rb25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/yahns/openssl_client.rb b/lib/yahns/openssl_client.rb
index 5842e97..ffa4b3e 100644
--- a/lib/yahns/openssl_client.rb
+++ b/lib/yahns/openssl_client.rb
@@ -8,6 +8,31 @@ require_relative 'sendfile_compat'
 module Yahns::OpenSSLClient # :nodoc:
   include Yahns::SendfileCompat
 
+  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
+
+  # this is special, called during IO initialization in Ruby
+  def sync
+    defined?(@ssl) ? @ssl.sync : super
+  end
+
   def yahns_init_ssl(ssl_ctx)
     @need_accept = true
     @ssl = OpenSSL::SSL::SSLSocket.new(self, ssl_ctx)