Class: Excon::SSLSocket
Constant Summary collapse
- HAVE_NONBLOCK =
[:connect_nonblock, :read_nonblock, :write_nonblock].all? do |m| OpenSSL::SSL::SSLSocket.public_method_defined?(m) end
Constants included from Utils
Utils::CONTROL, Utils::DELIMS, Utils::ESCAPED, Utils::NONASCII, Utils::UNESCAPED, Utils::UNWISE
Instance Attribute Summary
Attributes inherited from Socket
Instance Method Summary collapse
-
#initialize(data = {}) ⇒ SSLSocket
constructor
A new instance of SSLSocket.
Methods inherited from Socket
#legacy_readline, #local_address, #local_port, #params, #params=, #read, #readline, #write
Methods included from Utils
#connection_uri, #escape_uri, #port_string, #query_string, #request_uri, #split_header_value, #unescape_form, #unescape_uri
Constructor Details
#initialize(data = {}) ⇒ SSLSocket
Returns a new instance of SSLSocket.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/excon/ssl_socket.rb', line 7 def initialize(data = {}) super # create ssl context ssl_context = OpenSSL::SSL::SSLContext.new # disable less secure options, when supported = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS end if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) |= OpenSSL::SSL::OP_NO_COMPRESSION end ssl_context. = ssl_context.ciphers = @data[:ciphers] if @data[:ssl_version] ssl_context.ssl_version = @data[:ssl_version] end if @data[:ssl_verify_peer] # turn verification on ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER if ca_file = @data[:ssl_ca_file] || ENV['SSL_CERT_FILE'] ssl_context.ca_file = ca_file end if ca_path = @data[:ssl_ca_path] || ENV['SSL_CERT_DIR'] ssl_context.ca_path = ca_path end if cert_store = @data[:ssl_cert_store] ssl_context.cert_store = cert_store end # no defaults, fallback to bundled unless ca_file || ca_path || cert_store ssl_context.cert_store = OpenSSL::X509::Store.new ssl_context.cert_store.set_default_paths # workaround issue #257 (JRUBY-6970) ca_file = DEFAULT_CA_FILE ca_file.gsub!(/^jar:/, '') if ca_file =~ /^jar:file:\// begin ssl_context.cert_store.add_file(ca_file) rescue Excon.display_warning("Excon unable to add file to cert store, ignoring: #{ca_file}\n[#{$!.class}] #{$!.}") end end if verify_callback = @data[:ssl_verify_callback] ssl_context.verify_callback = verify_callback end else # turn verification off ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE end # maintain existing API certificate_path = @data[:client_cert] || @data[:certificate_path] private_key_path = @data[:client_key] || @data[:private_key_path] private_key_pass = @data[:client_key_pass] || @data[:private_key_pass] if certificate_path && private_key_path ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(certificate_path)) if OpenSSL::PKey.respond_to? :read ssl_context.key = OpenSSL::PKey.read(File.read(private_key_path), private_key_pass) else ssl_context.key = OpenSSL::PKey::RSA.new(File.read(private_key_path), private_key_pass) end elsif @data.key?(:certificate) && @data.key?(:private_key) ssl_context.cert = OpenSSL::X509::Certificate.new(@data[:certificate]) if OpenSSL::PKey.respond_to? :read ssl_context.key = OpenSSL::PKey.read(@data[:private_key], private_key_pass) else ssl_context.key = OpenSSL::PKey::RSA.new(@data[:private_key], private_key_pass) end end if @data[:proxy] request = 'CONNECT ' << @data[:host] << port_string(@data.merge(:omit_default_port => false)) << Excon::HTTP_1_1 request << 'Host: ' << @data[:host] << port_string(@data) << Excon::CR_NL if @data[:proxy][:password] || @data[:proxy][:user] auth = ['' << @data[:proxy][:user].to_s << ':' << @data[:proxy][:password].to_s].pack('m').delete(Excon::CR_NL) request << 'Proxy-Authorization: Basic ' << auth << Excon::CR_NL end request << 'Proxy-Connection: Keep-Alive' << Excon::CR_NL request << Excon::CR_NL # write out the proxy setup request @socket.write(request) # eat the proxy's connection response Excon::Response.parse(self, :expects => 200, :method => 'CONNECT') end # convert Socket to OpenSSL::SSL::SSLSocket @socket = OpenSSL::SSL::SSLSocket.new(@socket, ssl_context) @socket.sync_close = true # Server Name Indication (SNI) RFC 3546 if @socket.respond_to?(:hostname=) @socket.hostname = @data[:host] end begin if @nonblock begin @socket.connect_nonblock rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable select_with_timeout(@socket, :connect_read) && retry rescue IO::WaitWritable select_with_timeout(@socket, :connect_write) && retry end else @socket.connect end rescue Errno::ETIMEDOUT, Timeout::Error raise Excon::Errors::Timeout.new('connect timeout reached') end # verify connection if @data[:ssl_verify_peer] @socket.post_connection_check(@data[:ssl_verify_peer_host] || @data[:host]) end @socket end |