class HTTPX::SSL

  1. lib/httpx/io/ssl.rb
  2. lib/httpx/plugins/proxy/ssh.rb
  3. show all
Superclass: TCP

Constants

TLS_OPTIONS = { alpn_protocols: %w[h2 http/1.1].freeze }  

rubocop:disable Style/MutableConstant

Attributes

Public Class methods

new(_, _, options)
[show source]
   # File lib/httpx/io/ssl.rb
18 def initialize(_, _, options)
19   super
20 
21   ctx_options = TLS_OPTIONS.merge(options.ssl)
22   @sni_hostname = ctx_options.delete(:hostname) || @hostname
23 
24   if @keep_open && @io.is_a?(OpenSSL::SSL::SSLSocket)
25     # externally initiated ssl socket
26     @ctx = @io.context
27     @state = :negotiated
28   else
29     @ctx = OpenSSL::SSL::SSLContext.new
30     @ctx.set_params(ctx_options) unless ctx_options.empty?
31     unless @ctx.session_cache_mode.nil? # a dummy method on JRuby
32       @ctx.session_cache_mode =
33         OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
34     end
35 
36     yield(self) if block_given?
37   end
38 
39   @verify_hostname = @ctx.verify_hostname
40 end

Public Instance methods

can_verify_peer?()
[show source]
   # File lib/httpx/io/ssl.rb
71 def can_verify_peer?
72   @ctx.verify_mode == OpenSSL::SSL::VERIFY_PEER
73 end
connect()
[show source]
    # File lib/httpx/io/ssl.rb
 94 def connect
 95   super
 96   return if @state == :negotiated ||
 97             @state != :connected
 98 
 99   unless @io.is_a?(OpenSSL::SSL::SSLSocket)
100     if (hostname_is_ip = (@ip == @sni_hostname))
101       # IPv6 address would be "[::1]", must turn to "0000:0000:0000:0000:0000:0000:0000:0001" for cert SAN check
102       @sni_hostname = @ip.to_string
103       # IP addresses in SNI is not valid per RFC 6066, section 3.
104       @ctx.verify_hostname = false
105     end
106 
107     @io = OpenSSL::SSL::SSLSocket.new(@io, @ctx)
108 
109     @io.hostname = @sni_hostname unless hostname_is_ip
110     @io.session = @ssl_session unless ssl_session_expired?
111     @io.sync_close = true
112   end
113   try_ssl_connect
114 end
connected?()
[show source]
   # File lib/httpx/io/ssl.rb
82 def connected?
83   @state == :negotiated
84 end
expired?()
[show source]
   # File lib/httpx/io/ssl.rb
86 def expired?
87   super || ssl_session_expired?
88 end
protocol()
[show source]
   # File lib/httpx/io/ssl.rb
51 def protocol
52   @io.alpn_protocol || super
53 rescue StandardError
54   super
55 end
session_new_cb(&pr)
[show source]
   # File lib/httpx/io/ssl.rb
43 def session_new_cb(&pr)
44   @ctx.session_new_cb = proc { |_, sess| pr.call(sess) }
45 end
ssl_session_expired?()
[show source]
   # File lib/httpx/io/ssl.rb
90 def ssl_session_expired?
91   @ssl_session.nil? || Process.clock_gettime(Process::CLOCK_REALTIME) >= (@ssl_session.time.to_f + @ssl_session.timeout)
92 end
try_ssl_connect()
[show source]
    # File lib/httpx/io/ssl.rb
116 def try_ssl_connect
117   ret = @io.connect_nonblock(exception: false)
118   log(level: 3, color: :cyan) { "TLS CONNECT: #{ret}..." }
119   case ret
120   when :wait_readable
121     @interests = :r
122     return
123   when :wait_writable
124     @interests = :w
125     return
126   end
127   @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && @verify_hostname
128   transition(:negotiated)
129   @interests = :w
130 end
verify_hostname(host)
[show source]
   # File lib/httpx/io/ssl.rb
75 def verify_hostname(host)
76   return false if @ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE
77   return false if !@io.respond_to?(:peer_cert) || @io.peer_cert.nil?
78 
79   OpenSSL::SSL.verify_certificate_identity(@io.peer_cert, host)
80 end