Packages
gnat
0.1.3
1.16.0
1.15.2
1.15.1
1.15.0
1.14.1
1.14.0
1.14.0-rc1
1.14.0-rc0
1.13.1
1.13.0
1.12.1
1.12.0
1.11.1
1.11.0
1.10.2
1.10.2-rc1
1.10.2-rc0
1.10.1
1.10.0
1.9.1
1.9.0
1.8.5
1.8.4
1.8.3
1.8.2
1.8.1
1.7.1
1.7.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.0
1.3.0-rc0
1.2.1
1.2.0
1.1.3
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
0.7.0
0.6.1
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
A nats client in pure elixir. Resilience, Performance, Ease-of-Use.
Current section
Files
Jump to
Current section
Files
lib/gnat/handshake.ex
defmodule Gnat.Handshake do
alias Gnat.Parser
@moduledoc """
This module provides a single function which handles all of the variations of establishing a connection to a gnatsd server and just returns {:ok, socket} or {:error, reason}
"""
def connect(settings) do
{:ok, tcp} = :gen_tcp.connect(settings.host, settings.port, settings.tcp_opts)
perform_handshake(tcp, settings)
end
defp perform_handshake(tcp, connection_settings) do
receive do
{:tcp, ^tcp, operation} ->
{_, [{:info, options}]} = Parser.parse(Parser.new, operation)
{:ok, socket} = upgrade_connection(tcp, options, connection_settings)
send_connect_message(socket, options, connection_settings)
{:ok, socket}
after 1000 ->
{:error, "timed out waiting for info"}
end
end
defp socket_write(%{tls: true}, socket, iodata), do: :ssl.send(socket, iodata)
defp socket_write(_, socket, iodata), do: :gen_tcp.send(socket, iodata)
defp send_connect_message(socket, %{auth_required: true}=_options, %{username: username, password: password}=connection_settings) do
opts = Poison.Encoder.encode(%{user: username, pass: password, verbose: false}, strict_keys: true)
socket_write(connection_settings, socket, "CONNECT #{opts}\r\n")
end
defp send_connect_message(socket, _options, connection_settings) do
socket_write(connection_settings, socket, "CONNECT {\"verbose\": false}\r\n")
end
defp upgrade_connection(tcp, %{tls_required: true}, %{tls: true, ssl_opts: opts}) do
:ok = :inet.setopts(tcp, [active: true])
:ssl.connect(tcp, opts, 1_000)
end
defp upgrade_connection(tcp, _server_settings, _connection_settions), do: {:ok, tcp}
end