Class: Soren::Connection

Inherits:
Object show all
Defined in:
lib/soren/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host: nil, port: nil, scheme: nil, uri: nil, options: {}) ⇒ Connection

: (?host: untyped, ?port: untyped, ?scheme: untyped, ?uri: untyped, ?options: untyped) -> void



23
24
25
26
27
28
29
30
# File 'lib/soren/connection.rb', line 23

def initialize(host: nil, port: nil, scheme: nil, uri: nil, options: {})
  host, port, scheme = resolve_connection_parts(host: host, port: port, scheme: scheme, uri: uri)

  @host = Soren::Types::Connection::Host.new(host) #: Soren::Types::Connection::Host
  @port = Soren::Types::Connection::Port.new(port) #: Soren::Types::Connection::Port
  @scheme = Soren::Types::Connection::Scheme.new(scheme) #: Soren::Types::Connection::Scheme
  @options = Soren::Options.new(options) #: Soren::Options
end

Instance Attribute Details

#optionsObject (readonly)

: Soren::Options?



20
21
22
# File 'lib/soren/connection.rb', line 20

def options
  @options
end

Instance Method Details

#open_socketObject

: -> (TCPSocket | OpenSSL::SSL::SSLSocket)



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
# File 'lib/soren/connection.rb', line 33

def open_socket
  deadline = Deadline.start(@options.connect_timeout.to_f)
  tcp = open_tcp_socket(deadline&.remaining)

  return tcp unless @scheme.https?

  ctx = OpenSSL::SSL::SSLContext.new
  ssl = OpenSSL::SSL::SSLSocket.new(tcp, ctx)
  ssl.hostname = @host.to_s
  ssl_connect_with_timeout(ssl, deadline)
  ssl
rescue Soren::Error::TimeoutError => e
  tcp&.close
  raise e
rescue Timeout::Error, Errno::ETIMEDOUT => e
  tcp&.close
  raise Soren::Error::TimeoutError, "connection timeout: #{e.message}"
rescue OpenSSL::SSL::SSLError => e
  tcp&.close
  raise Soren::Error::SSLError, "SSL error: #{e.message}"
rescue ::SocketError => e
  tcp&.close
  raise Soren::Error::DNSFailure, "DNS lookup failed: #{e.message}"
rescue Errno::ECONNREFUSED => e
  tcp&.close
  raise Soren::Error::ConnectionRefused, "connection refused: #{e.message}"
rescue SystemCallError, IOError => e
  tcp&.close
  raise Soren::Error::ConnectionError, "connection error: #{e.message}"
end

#send(request) ⇒ Object

: (Soren::Request) -> Soren::Response



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/soren/connection.rb', line 65

def send(request)
  socket = open_socket
  io = Soren::Socket::IO.new(socket, request, @options, host: @host)
  io.write_request
  parsed_response = io.read_response
  Soren::Response.new(parsed_response)
rescue Timeout::Error, Errno::ETIMEDOUT => e
  raise Soren::Error::TimeoutError, "connection timeout: #{e.message}"
rescue SystemCallError, IOError => e
  raise Soren::Error::ReadError, "read error: #{e.message}"
ensure
  socket&.close
end