Class: HTTPX::SSL
Direct Known Subclasses
Constant Summary collapse
- TLS_OPTIONS =
rubocop:disable Style/MutableConstant
{ alpn_protocols: %w[h2 http/1.1].freeze }
Constants included from Loggable
Loggable::COLORS, Loggable::USE_DEBUG_LOG
Instance Attribute Summary collapse
-
#ssl_session ⇒ Object
writeonly
Sets the attribute ssl_session.
Attributes inherited from TCP
#addresses, #interests, #ip, #port, #state
Instance Method Summary collapse
- #can_verify_peer? ⇒ Boolean
- #connect ⇒ Object
- #connected? ⇒ Boolean
- #expired? ⇒ Boolean
-
#initialize(_, _, options) ⇒ SSL
constructor
A new instance of SSL.
-
#protocol ⇒ Object
in jruby, alpn_protocol may return “” github.com/jruby/jruby-openssl/issues/287.
-
#session_new_cb ⇒ Object
session_new_cb not implemented under JRuby.
- #ssl_session_expired? ⇒ Boolean
- #try_ssl_connect ⇒ Object
- #verify_hostname(host) ⇒ Object
Methods inherited from TCP
#add_addresses, #close, #closed?, #inspect, #read, #socket, #to_io, #write
Methods included from Loggable
Constructor Details
#initialize(_, _, options) ⇒ SSL
Returns a new instance of SSL.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/httpx/io/ssl.rb', line 18 def initialize(_, _, ) super = TLS_OPTIONS.merge(.ssl) @sni_hostname = .delete(:hostname) || @hostname if @keep_open && @io.is_a?(OpenSSL::SSL::SSLSocket) # externally initiated ssl socket @ctx = @io.context @state = :negotiated else @ctx = OpenSSL::SSL::SSLContext.new @ctx.set_params() unless .empty? unless @ctx.session_cache_mode.nil? # a dummy method on JRuby @ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE end yield(self) if block_given? end @verify_hostname = @ctx.verify_hostname end |
Instance Attribute Details
#ssl_session=(value) ⇒ Object (writeonly)
Sets the attribute ssl_session
16 17 18 |
# File 'lib/httpx/io/ssl.rb', line 16 def ssl_session=(value) @ssl_session = value end |
Instance Method Details
#can_verify_peer? ⇒ Boolean
71 72 73 |
# File 'lib/httpx/io/ssl.rb', line 71 def can_verify_peer? @ctx.verify_mode == OpenSSL::SSL::VERIFY_PEER end |
#connect ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/httpx/io/ssl.rb', line 94 def connect super return if @state == :negotiated || @state != :connected unless @io.is_a?(OpenSSL::SSL::SSLSocket) if (hostname_is_ip = (@ip == @sni_hostname)) # IPv6 address would be "[::1]", must turn to "0000:0000:0000:0000:0000:0000:0000:0001" for cert SAN check @sni_hostname = @ip.to_string # IP addresses in SNI is not valid per RFC 6066, section 3. @ctx.verify_hostname = false end @io = OpenSSL::SSL::SSLSocket.new(@io, @ctx) @io.hostname = @sni_hostname unless hostname_is_ip @io.session = @ssl_session unless ssl_session_expired? @io.sync_close = true end try_ssl_connect end |
#connected? ⇒ Boolean
82 83 84 |
# File 'lib/httpx/io/ssl.rb', line 82 def connected? @state == :negotiated end |
#expired? ⇒ Boolean
86 87 88 |
# File 'lib/httpx/io/ssl.rb', line 86 def expired? super || ssl_session_expired? end |
#protocol ⇒ Object
in jruby, alpn_protocol may return “” github.com/jruby/jruby-openssl/issues/287
60 61 62 63 64 |
# File 'lib/httpx/io/ssl.rb', line 60 def protocol @io.alpn_protocol || super rescue StandardError super end |
#session_new_cb ⇒ Object
session_new_cb not implemented under JRuby
48 49 50 |
# File 'lib/httpx/io/ssl.rb', line 48 def session_new_cb(&pr) @ctx.session_new_cb = proc { |_, sess| pr.call(sess) } end |
#ssl_session_expired? ⇒ Boolean
90 91 92 |
# File 'lib/httpx/io/ssl.rb', line 90 def ssl_session_expired? @ssl_session.nil? || Process.clock_gettime(Process::CLOCK_REALTIME) >= (@ssl_session.time.to_f + @ssl_session.timeout) end |
#try_ssl_connect ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/httpx/io/ssl.rb', line 116 def try_ssl_connect ret = @io.connect_nonblock(exception: false) log(level: 3, color: :cyan) { "TLS CONNECT: #{ret}..." } case ret when :wait_readable @interests = :r return when :wait_writable @interests = :w return end @io.post_connection_check(@sni_hostname) if @ctx.verify_mode != OpenSSL::SSL::VERIFY_NONE && @verify_hostname transition(:negotiated) @interests = :w end |
#verify_hostname(host) ⇒ Object
75 76 77 78 79 80 |
# File 'lib/httpx/io/ssl.rb', line 75 def verify_hostname(host) return false if @ctx.verify_mode == OpenSSL::SSL::VERIFY_NONE return false if !@io.respond_to?(:peer_cert) || @io.peer_cert.nil? OpenSSL::SSL.verify_certificate_identity(@io.peer_cert, host) end |