class HTTPClient::SSLSocket

Wraps up OpenSSL::SSL::SSLSocket and offers debugging features.

Constants

DEFAULT_SSL_PROTOCOL

Public Class Methods

create_socket(session) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 459
def self.create_socket(session)
  opts = {
    :connect_timeout => session.connect_timeout * 1000,
    # send_timeout is ignored in JRuby
    :so_timeout => session.receive_timeout * 1000,
    :tcp_keepalive => session.tcp_keepalive,
    :debug_dev => session.debug_dev
  }
  socket = nil
  begin
    if session.proxy
      site = session.proxy || session.dest
      socket = JavaSocketWrap.connect(Socket.new, site, opts)
      session.connect_ssl_proxy(JavaSocketWrap.new(socket), Util.urify(session.dest.to_s))
    end
    new(socket, session.dest, session.ssl_config, opts)
  rescue
    socket.close if socket
    raise
  end
end
new(socket, dest, config, opts = {}) click to toggle source
Calls superclass method HTTPClient::JavaSocketWrap::new
# File lib/httpclient/jruby_ssl_socket.rb, line 482
def initialize(socket, dest, config, opts = {})
  @config = config
  begin
    @ssl_socket = create_ssl_socket(socket, dest, config, opts)
    ssl_version = java_ssl_version(config)
    @ssl_socket.setEnabledProtocols([ssl_version].to_java(java.lang.String)) if ssl_version != DEFAULT_SSL_PROTOCOL
    if config.ciphers != SSLConfig::CIPHERS_DEFAULT
      @ssl_socket.setEnabledCipherSuites(config.ciphers.to_java(java.lang.String))
    end
    ssl_connect(dest.host)
  rescue java.security.GeneralSecurityException => e
    raise OpenSSL::SSL::SSLError.new(e.getMessage)
  rescue java.io.IOException => e
    raise OpenSSL::SSL::SSLError.new("#{e.class}: #{e.getMessage}")
  end

  super(@ssl_socket, opts[:debug_dev])
end

Public Instance Methods

<<(str) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 79
def <<(str)
  rv = @ssl_socket.write(str)
  debug(str)
  rv
end
close() click to toggle source
# File lib/httpclient/ssl_socket.rb, line 48
def close
  @ssl_socket.close
  @socket.close
end
closed?() click to toggle source
# File lib/httpclient/ssl_socket.rb, line 53
def closed?
  @socket.closed?
end
create_ssl_context(config) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 509
def create_ssl_context(config)
  unless config.cert_store_crl_items.empty?
    raise NotImplementedError.new('Manual CRL configuration is not yet supported')
  end

  km = nil
  if config.client_cert && config.client_key
    loader = KeyStoreLoader.new
    loader.add(config.client_cert, config.client_key, config.client_key_pass)
    kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
    kmf.init(loader.keystore, KeyStoreLoader::PASSWORD)
    km = kmf.getKeyManagers
  end

  trust_store = nil
  verify_callback = config.verify_callback || config.method(:default_verify_callback)
  if !config.verify?
    tmf = VerifyNoneTrustManagerFactory.new(verify_callback)
  else
    tmf = SystemTrustManagerFactory.new(verify_callback)
    loader = TrustStoreLoader.new
    config.cert_store_items.each do |item|
      loader.add(item)
    end
    trust_store = loader.trust_store
  end
  tmf.init(trust_store)
  tm = tmf.getTrustManagers

  ctx = SSLContext.getInstance(java_ssl_version(config))
  ctx.init(km, tm, nil)
  if config.timeout
    ctx.getClientSessionContext.setSessionTimeout(config.timeout)
  end
  ctx
end
create_ssl_socket(socket, dest, config, opts) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 546
def create_ssl_socket(socket, dest, config, opts)
  ctx = create_ssl_context(config)
  factory = ctx.getSocketFactory
  if socket
    ssl_socket = factory.createSocket(socket, dest.host, dest.port, true)
  else
    ssl_socket = factory.createSocket
    JavaSocketWrap.connect(ssl_socket, dest, opts)
  end
  ssl_socket
end
eof?() click to toggle source
# File lib/httpclient/ssl_socket.rb, line 57
def eof?
  @ssl_socket.eof?
end
flush() click to toggle source
# File lib/httpclient/ssl_socket.rb, line 85
def flush
  @ssl_socket.flush
end
gets(rs) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 61
def gets(rs)
  str = @ssl_socket.gets(rs)
  debug(str)
  str
end
java_ssl_version(config) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 501
def java_ssl_version(config)
  if config.ssl_version == :auto
    DEFAULT_SSL_PROTOCOL
  else
    config.ssl_version.to_s.tr('_', '.')
  end
end
peer_cert() click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 558
def peer_cert
  @peer_cert
end
read(size, buf = nil) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 67
def read(size, buf = nil)
  str = @ssl_socket.read(size, buf)
  debug(str)
  str
end
readpartial(size, buf = nil) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 73
def readpartial(size, buf = nil)
  str = @ssl_socket.readpartial(size, buf)
  debug(str)
  str
end
sync() click to toggle source
# File lib/httpclient/ssl_socket.rb, line 89
def sync
  @ssl_socket.sync
end
sync=(sync) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 93
def sync=(sync)
  @ssl_socket.sync = sync
end

Private Instance Methods

check_mask(value, mask) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 128
def check_mask(value, mask)
  value & mask == mask
end
create_openssl_socket(socket) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 132
def create_openssl_socket(socket)
  ssl_socket = nil
  if OpenSSL::SSL.const_defined?("SSLContext")
    ctx = OpenSSL::SSL::SSLContext.new
    @config.set_context(ctx)
    ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
  else
    ssl_socket = OpenSSL::SSL::SSLSocket.new(socket)
    @config.set_context(ssl_socket)
  end
  ssl_socket
end
debug(str) click to toggle source
# File lib/httpclient/ssl_socket.rb, line 145
def debug(str)
  @debug_dev << str if @debug_dev && str
end
post_connection_check(hostname) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 575
def post_connection_check(hostname)
  if !@config.verify?
    return
  else
    BrowserCompatHostnameVerifier.new.verify(hostname, @peer_cert.cert)
  end
end
ssl_connect(hostname) click to toggle source
# File lib/httpclient/jruby_ssl_socket.rb, line 564
def ssl_connect(hostname)
  @ssl_socket.startHandshake
  ssl_session = @ssl_socket.getSession
  @peer_cert = JavaCertificate.new(ssl_session.getPeerCertificates.first)
  if $DEBUG
    warn("Protocol version: #{ssl_session.getProtocol}")
    warn("Cipher: #{@ssl_socket.getSession.getCipherSuite}")
  end
  post_connection_check(hostname)
end