Class: Excon::SSLSocket
Constant Summary collapse
- HAVE_NONBLOCK =
[:connect_nonblock, :read_nonblock, :write_nonblock].all? {|m| OpenSSL::SSL::SSLSocket.public_method_defined?(m) }
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
#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.
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 |
# File 'lib/excon/ssl_socket.rb', line 8 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_path = ENV['SSL_CERT_DIR'] || @data[:ssl_ca_path] ssl_context.ca_path = ca_path elsif ca_file = ENV['SSL_CERT_FILE'] || @data[:ssl_ca_file] ssl_context.ca_file = ca_file else # attempt default, fallback to bundled 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 => e Excon.display_warning("Excon unable to add file to cert store, ignoring: #{ca_file}\n[#{e.class}] #{e.}") 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] if certificate_path && private_key_path ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(certificate_path)) ssl_context.key = OpenSSL::PKey::RSA.new(File.read(private_key_path)) elsif @data.has_key?(:certificate) && @data.has_key?(:private_key) ssl_context.cert = OpenSSL::X509::Certificate.new(@data[:certificate]) ssl_context.key = OpenSSL::PKey::RSA.new(@data[:private_key]) 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(@socket, { :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 Timeout.timeout(@data[:connect_timeout]) do if @nonblock while true begin @socket.connect_nonblock break # connect succeeded rescue OpenSSL::SSL::SSLError => error # would block, rescue and retry as select is non-helpful unless error. == 'read would block' raise error end end end else @socket.connect end end rescue Timeout::Error raise Excon::Errors::Timeout.new('connect timeout reached') end # verify connection if @data[:ssl_verify_peer] @socket.post_connection_check(@data[:host]) end @socket end |