astahjmo

astahjmo

Help with Gun http/websocket connection - TLS Client: wait_cert_cr at ssl_handshake

I’m trying to use Gun to communicate with the Discord API for educational purposes (I chose Gun for being a lower-level tool to understand some complexities), and I’m having issues during the handshake with the Discord WebSocket gateway. I’m receiving the following error:

(MatchError) no match of right hand side value: {:error, {:down, {:shutdown, {:tls_alert, {:internal_error, ~c"TLS client: In state wait_cert_cr at ssl_handshake .erl:364 generated CLIENT ALERT: Fatal - Internal Error\n {unexpected_error,undef}"}}}}}

Please note that my :gun.ws_upgrade is failing during the handshake when transitioning from HTTP to WebSocket. I have no idea what might be wrong to reach this point with this error. Can you shed some light on what could be the issue and how to fix it?

Here is my code

  def test do
    opts2 = %{
        connect_timeout: 60000,
        retry: 10,
        retry_timeout: 300,
        transport: :tls,
        tls_opts: [
          verify: :verify_none,
          cacerts: :certifi.cacerts(),
          depth: 99,
          reuse_sessions: false
        ],
        http_opts: %{version: :"HTTP/1.1"},
        protocols: [:http],
    }
    opts = %{
        connect_timeout: 60000,
        retry: 10,
        retry_timeout: 300,
        transport: :tls,
        tls_opts: [
          verify: :verify_peer,
          cacertfile: CAStore.file_path(),
          depth: 99,
          reuse_sessions: false,
          verify_fun: {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'gateway.discord.gg']}
        ],
        http_opts: %{version: :"HTTP/1.1"},
        protocols: [:http],
    }
    {:ok, conn} = :gun.open('discord.com', 443, opts2)
    {:ok, _} = :gun.await_up(conn)
    stream = :gun.get(conn, "/api/v10/gateway")
    {response, :nofin, 200, headers} = :gun.await(conn, stream)
    {:ok, body} = :gun.await_body(conn, stream)
    {:ok, map} = Jason.decode(body)
    IO.inspect(map["url"])

    {:ok, conn} = :gun.open('gateway.discord.gg', 443, opts)
    {:ok, _} = :gun.await_up(conn)
    :timer.sleep(1000)
    stream = :gun.ws_upgrade(conn, '/?v=10&encoding=json', headers, opts)
    receive do
      {:gun_upgrade, _, _} ->
        IO.puts("WebSocket Upgrade Successful")
        connected(conn)
      {:gun_error, _reason} ->
        IO.puts("WebSocket Upgrade Error")
    after
      5000 ->
        IO.puts("WebSocket Upgrade Timeout")
    end
  end

  defp connected(conn) do
    receive do
      something ->
        IO.puts("Received WebSocket Text Frame")
        connected(conn)
      {:gun_close, _status, _reason} ->
        IO.puts("WebSocket Connection Closed")
    after
      5000 ->
        IO.puts("WebSocket Communication Timeout")
    end
  end

First Post!

7stud

7stud

I got a gun example with a websocket upgrade to work a long time ago. Maybe it will help.

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement