class Redis::Connection::SSLSocket

Public Class Methods

connect(host, port, timeout, ssl_params) click to toggle source
# File lib/redis/connection/ruby.rb, line 260
def self.connect(host, port, timeout, ssl_params)
  # Note: this is using Redis::Connection::TCPSocket
  tcp_sock = TCPSocket.connect(host, port, timeout)

  ctx = OpenSSL::SSL::SSLContext.new
  ctx.set_params(ssl_params) if ssl_params && !ssl_params.empty?

  ssl_sock = new(tcp_sock, ctx)
  ssl_sock.hostname = host

  begin
    # Initiate the socket connection in the background. If it doesn't fail
    # immediately it will raise an IO::WaitWritable (Errno::EINPROGRESS)
    # indicating the connection is in progress.
    # Unlike waiting for a tcp socket to connect, you can't time out ssl socket
    # connections during the connect phase properly, because IO.select only partially works.
    # Instead, you have to retry.
    ssl_sock.connect_nonblock
  rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable
    if IO.select([ssl_sock], nil, nil, timeout)
      retry
    else
      raise TimeoutError
    end
  rescue IO::WaitWritable
    if IO.select(nil, [ssl_sock], nil, timeout)
      retry
    else
      raise TimeoutError
    end
  end

  unless ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE
    ssl_sock.post_connection_check(host)
  end

  ssl_sock
end