NaN

NaN

Getting :gun_error {:stream_error, :protocol_error, :"Stream reset by server."}

:gun_error : {:stream_error, :protocol_error, :"Stream reset by server."}

In Phoenix. The stream ref is created, but somewhere before upgrade the above error presents itself. The request is never passed to &Node.Socket.init/2 Non-tls connection work fine.

Certs from GlobalSign. The same cert works fine over the web for Phx.

Any ideas??

{:gun, "~> 2.0"}
{:plug_cowboy, "~> 2.5"}

server:

  defmodule Node.Server do
      use GenServer
      
      def start_link(opts) do
        GenServer.start_link(__MODULE__, opts, name: __MODULE__)
      end
      
      def init(opts) do
        routes = [
          {:_,
           [
             {"/", Node.Socket, []}
           ]}
        ]
      
        # Compile the routes into a dispatch list
        dispatch = :cowboy_router.compile(routes)
      
        {protocol, start_fn, opts} =
          case System.get_env("IS_DOCKER") do
            "true" ->
              {:https, &:cowboy.start_tls/3,
               [
                 {:port, opts.port},
                 {:cacertfile, "/app/priv/ssl/http/ca.crt"},
                 {:certfile, "/app/priv/ssl/http/server.crt"},
                 {:keyfile, "/app/priv/ssl/http/server.key"},
               ]}
      
            _ ->
              {:http, &:cowboy.start_clear/3,
               [
                 {:port, opts.port}
               ]}
          end
      
        {:ok, _} =
          start_fn.(
            protocol,
            opts,
            %{
              env: %{dispatch: dispatch}
            }
          )
      
        {:ok, %{}}
      end
      end

client:

  defp connect_to_node({admin_domain, admin_port, port} = node, token, state) do
    admin_domain = admin_domain |> String.to_charlist()

    options =
        case System.get_env("IS_DOCKER") do
        "true" ->
          %{
            transport: :tls,
            tls_opts: [
              {:port, port},
              {:verify, :verify_peer},
              {:server_name_indication, admin_domain},
              {:customize_hostname_check, [{:match_fun, :public_key.pkix_verify_hostname_match_fun(:https)}]},
              {:cacerts, :public_key.cacerts_get()}
            ]
          }

        _ ->
          %{
            tcp_opts: [{:port, port}]
          }
       end

    {:ok, conn_pid} = :gun.open(admin_domain, admin_port, options)

    Logger.debug("Attempting to connect to Admin Node @ #{admin_domain}:#{admin_port} from local port #{port}")

    case :gun.await_up(conn_pid) do
      {:ok, _} ->
        token = token || fetch_token()

        headers = %{
          "authorization" => "#{token}"
        }

        # created fine here
        stream_ref = :gun.ws_upgrade(conn_pid, ~c"/", headers) |> IO.inspect()

        Node.Identity.set(%{
          connected_node: node
        })

        if Node.Identity.get().primary_node != node do
          :timer.send_after(900_000, self(), :connect_to_primary)
        end

        {:ok, %{state | conn_pid: conn_pid, stream_ref: stream_ref}}

      {:error, error} ->
        Logger.debug("Failed to connect to Admin Node @ #{admin_domain}:#{admin_port} from local port #{port} | Error: #{inspect(error)}")
        :gun.shutdown(conn_pid)
        {:error, state}
    end
  end

Node.Socket.inti : (again, non-tls auths fine, but this is never called when using tls)

  def init(req, _opts) do
    Logger.debug("Initiating websocket connection with request: #{inspect(req)}")

    case Map.get(req.headers, "authorization") do
      nil ->
        :cowboy_req.reply(401, req)
        {:cowboy_websocket, req, %{}}

      auth ->
        {:ok, shared_key} = Node.Identity.shared_key()

        case Node.Auth.decrypt(auth, shared_key) do
          {:ok, _decrypted} ->
            {:cowboy_websocket, req, %{}, %{idle_timeout: :infinity}}

          _ ->
            :cowboy_req.reply(401, req)
            {:cowboy_websocket, req, %{}}
        end
    end
  end

1/9/23 ~6:30 moved due to cat mistake

Most Liked

NaN

NaN

No worries. TY… its just as likely you mention something that solves it. worst case someone learns something.

Last Post!

NaN

NaN

I have used multiple sets of tls_opts at this point.

verify_none, with cacerts, with a cacertfile, etc… all of them render the same error from rst_stream_frame unless of course I dont pass the opts needed to get past handshake. In which case I can see the hand shake fail on server and client

this is the only place I can find in the code that produces the error… any idea why?

rst_stream_frame(State0, StreamID, Reason, EvHandler, EvHandlerState0) ->
	case take_stream(State0, StreamID) of
		{#stream{ref=StreamRef, reply_to=ReplyTo}, State} ->
			ReplyTo ! {gun_error, self(), stream_ref(State0, StreamRef),
				{stream_error, Reason, 'Stream reset by server.'}},
			EvHandlerState = EvHandler:cancel(#{
				stream_ref => stream_ref(State, StreamRef),
				reply_to => ReplyTo,
				endpoint => remote,
				reason => Reason
			}, EvHandlerState0),
			{{state, State}, EvHandlerState};
		error ->
			{{state, State0}, EvHandlerState0}
	end.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42576 114
New

We're in Beta

About us Mission Statement