123456789_123456789_123456789_123456789_123456789_

Class: Bundler::CLI::Doctor::SSL

Relationships & Source Files
Namespace Children
Modules:
Inherits: Object
Defined in: lib/bundler/cli/doctor/ssl.rb

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(options) ⇒ SSL

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 10

def initialize(options)
  @options = options
end

Instance Attribute Details

#bundler_connection_successful?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 71

def bundler_connection_successful?
  Bundler.ui.info("\nTrying connections to #{uri}:\n")

  bundler_uri = Gem::URI(uri.to_s)
  Bundler::Fetcher.new(
    Bundler::Source::Rubygems::Remote.new(bundler_uri)
  ).send(:connection).request(bundler_uri)

  Bundler.ui.info("Bundler:       success")

  true
rescue StandardError => error
  Bundler.ui.warn("Bundler:       failed     (#{Explanation.explain_bundler_or_rubygems_error(error)})")

  false
end

#net_http_connection_successful?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 99

def net_http_connection_successful?
  ::Gem::Net::HTTP.new(uri.host, uri.port).tap do |http|
    http.use_ssl = true
    http.min_version = tls_version
    http.max_version = tls_version
    http.verify_mode = verify_mode
  end.start

  Bundler.ui.info("Ruby net/http: success")
  warn_on_unsupported_tls12

  true
rescue StandardError => error
  Bundler.ui.warn(<<~MSG)
    Ruby net/http: failed

    Unfortunately, this Ruby can't connect to #{host}.

    #{Explanation.explain_net_http_error(error, host, tls_version)}
  MSG

  false
end

#openssl_installed?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 48

def openssl_installed?
  require "openssl"

  true
rescue LoadError
  Bundler.ui.warn(<<~MSG)
    Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}.
    You'll need to recompile or reinstall Ruby with OpenSSL support and try again.
  MSG

  false
end

#options (readonly)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 8

attr_reader :options

#rubygem_connection_successful?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 88

def rubygem_connection_successful?
  Gem::RemoteFetcher.fetcher.fetch_path(uri)
  Bundler.ui.info("RubyGems:      success")

  true
rescue StandardError => error
  Bundler.ui.warn("RubyGems:      failed     (#{Explanation.explain_bundler_or_rubygems_error(error)})")

  false
end

Instance Method Details

#host (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 28

def host
  @options[:host] || "rubygems.org"
end

#output_ssl_environment (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 61

def output_ssl_environment
  Bundler.ui.info(<<~MESSAGE)
    Here's your OpenSSL environment:

    OpenSSL:       #{OpenSSL::VERSION}
    Compiled with: #{OpenSSL::OPENSSL_VERSION}
    Loaded with:   #{OpenSSL::OPENSSL_LIBRARY_VERSION}
  MESSAGE
end

#run

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 14

def run
  return unless openssl_installed?

  output_ssl_environment
  bundler_success = bundler_connection_successful?
  rubygem_success = rubygem_connection_successful?

  return unless net_http_connection_successful?

  Explanation.summarize(bundler_success, rubygem_success, host)
end

#tls_version (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 32

def tls_version
  @options[:"tls-version"].then do |version|
    "TLS#{version.sub(".", "_")}".to_sym if version
  end
end

#uri (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 44

def uri
  @uri ||= URI("https://#{host}")
end

#verify_mode (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 38

def verify_mode
  mode = @options[:"verify-mode"] || :peer

  @verify_mode ||= mode.then {|mod| OpenSSL::SSL.const_get("verify_#{mod}".upcase) }
end

#warn_on_unsupported_tls12 (private)

[ GitHub ]

  
# File 'lib/bundler/cli/doctor/ssl.rb', line 123

def warn_on_unsupported_tls12
  ctx = OpenSSL::SSL::SSLContext.new
  supported = true

  if ctx.respond_to?(:min_version=)
    begin
      ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
    rescue OpenSSL::SSL::SSLError, NameError
      supported = false
    end
  else
    supported = OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_2) # rubocop:disable Naming/VariableNumber
  end

  Bundler.ui.warn(<<~EOM) unless supported

    WARNING: Although your Ruby can connect to #{host} today, your OpenSSL is very old!
    WARNING: You will need to upgrade OpenSSL to use #{host}.

  EOM
end