File: ssl_socket.rb

package info (click to toggle)
ruby-riemann-client 1.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 228 kB
  • sloc: ruby: 1,271; makefile: 2
file content (58 lines) | stat: -rw-r--r-- 1,831 bytes parent folder | download
1
2
3
4
5
6
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
# frozen_string_literal: true

require 'openssl'
require_relative 'tcp_socket'

module Riemann
  class Client
    # Socket: A specialized socket that has been configure
    class SSLSocket < TcpSocket
      def initialize(options = {})
        super(options)
        @key_file = options[:key_file]
        @cert_file = options[:cert_file]
        @ca_file = options[:ca_file]
        @ssl_verify = options[:ssl_verify]
      end

      def ssl_context
        @ssl_context ||= OpenSSL::SSL::SSLContext.new.tap do |ctx|
          ctx.key = OpenSSL::PKey::RSA.new(File.read(@key_file))
          ctx.cert = OpenSSL::X509::Certificate.new(File.read(@cert_file))
          ctx.ca_file = @ca_file if @ca_file
          ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
          ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER if @ssl_verify
        end
      end

      # Internal: Connect to the give address within the timeout.
      #
      # Make an attempt to connect to a single address within the given timeout.
      #
      # Return the ::Socket when it is connected, or raise an Error if no
      # connection was possible.
      def connect_nonblock(addr, timeout)
        sock = super(addr, timeout)
        ssl_socket = OpenSSL::SSL::SSLSocket.new(sock, ssl_context)
        ssl_socket.sync = true

        begin
          ssl_socket.connect_nonblock
        rescue IO::WaitReadable
          unless IO.select([ssl_socket], nil, nil, timeout)
            raise Timeout, "Could not read from #{host}:#{port} in #{timeout} seconds"
          end

          retry
        rescue IO::WaitWritable
          unless IO.select(nil, [ssl_socket], nil, timeout)
            raise Timeout, "Could not write to #{host}:#{port} in #{timeout} seconds"
          end

          retry
        end
        ssl_socket
      end
    end
  end
end