Plug/Cowboy2 failing on all HTTP requests

Hello friends,

I’ve been using my free time in the last month or so to learn Elixir in the hope of replacing a Node.js server I wrote for a side project. To really understand the workings of Plug, I wanted to setup an ultra simple Plug/Cowboy HTTP server and start from there. Eventually, I’m sure I’ll move on to Phoenix, but I was really attracted to the simplicity of Plug as a starting point.

I uploaded the simplest “broken” version of my code to this repo. You should be able to easily clone and run that with mix, and I’ll also show the core code below:

defmodule PlugCowboy2Http2 do
  use Application

  def start(_type, _args) do
    children = [
      {
        Plug.Adapters.Cowboy2,
        scheme: :http,
        plug: PlugCowboy2Http2.Router
      }
    ]

    opts = [
      strategy: :one_for_one,
      name: PlugCowboy2Http2.Supervisor
    ]

    {:ok, _} = Supervisor.start_link(children, opts)
  end
end


defmodule PlugCowboy2Http2.Router do
  use Plug.Router

  plug(Plug.Logger)
  plug(:match)
  plug(:dispatch)

  match _ do
    send_resp(conn, 200, "Hello!")
  end
end

When I navigate my browser (Chromium: 70.0.3538.16) to http://localhost:4000 I seem to always crash a process. The browser receives an ERR_CONNECTION_RESET and the Elixir runtime prints the following message to console:

13:11:21.735 [error] Ranch protocol #PID<0.286.0> of listener PlugCowboy2Http2.Router.HTTP (cowboy_clear) terminated
** (exit) an exception was raised:
** (UndefinedFunctionError) function :cowboy_http.init/5 is undefined (module :cowboy_http is not available)
(cowboy) :cowboy_http.init(#PID<0.184.0>, PlugCowboy2Http2.Router.HTTP, #Port<0.5>, :ranch_tcp, %{env: %{dispatch: [{:, [], [{:, , Plug.Adapters.Cowboy2.Handler, {PlugCowboy2Http2.Router, }}]}]}, stream_handlers: [Plug.Adapters.Cowboy2.Stream]})
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

To add to the confusion, when I switch the :scheme option to :https and add a cert & key file, the server works perfectly. Can anyone show me where I’m going wrong?

1 Like

This means you are missing a library… o.O

Have you included cowboy2 in your project, not just Phoenix’s adaptor but also cowboy2 itself?
And taken out cowboy1?

Hi @OvermindDL1,

Included below is my mix.exs file:

defmodule PlugCowboy2Http2.MixProject do
  use Mix.Project

  def project do
    [
      app: :plug_cowboy2_http2,
      version: "0.1.0",
      elixir: "~> 1.7",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  def application do
    [
      extra_applications: [:logger],
      mod: {PlugCowboy2Http2, []}
    ]
  end

  defp deps do
    [
      {:cowboy, "~> 2.4.0"},
      {:plug, "~> 1.6.0"}
    ]
  end
end

I do have Cowboy and Plug included in my deps() function. Is there any other place I need to include them?

And just as a clarification, I’m not using Phoenix just yet. I was trying to get this working with only Plug and Cowboy as a learning experiment.

Well, I just cloned you repo and ran mix deps.get followed by mix compile and started the app with iex -S mix and I see Hello! in the browser. Are you sure you installed and/or compiled all dependencies correctly? I am most certain your code is correct.

2 Likes

What version of Elixir are you running, and what OS if you don’t mind me asking?

I’m running Elixir (1.7.3) with Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Mac os x 10.11 :stuck_out_tongue:

1 Like

Yeah I’d say wipe your _build directory, then rebuild all to start with.

1 Like

I got it working on my machine now. Ran the following commands:

mix deps.clean --all
rm -rf _build
rm mix.lock
mix deps.get
mix compile
mix run --no-halt

I thought I had tried this already, but maybe I had forgotten one of them. Anyhow, it seems to be working now. Thanks for your help.

3 Likes

I’ve had similar issues, and I think it’s a combination of elixir-ls running in the background, and me having different branches with different elixir versions (I was switching between 1.7.3 and 1.7.3-otp-21. I use neovim with https://github.com/autozimu/LanguageClient-neovim

In those cases, running mix deps.compile fixes it for me. I was about to give up on trying cowboy2 until I realized it was my setup that was the issue.

Hi!
Found almost the same issue building “Static Site with Elixir” like int this lesson - https://elixircasts.io/static-site-with-elixir

As I understood “plug” and “cowboy” was updated and now we should define them like this

defp deps do
    [
      {:plug_cowboy, "~> 2.0"}
    ]
end

So I updated my deps, and updated my code - and everything works like a charm!
Hope this helps)

I found a possible culprit for the above bugs:

It seems that when using elixir-vim, when Vim attempts to build your project upon saving a file, it can sometimes corrupt the build directory and cause odd problems during execution. To prevent this, I now start Vim via the following command: MIX_ENV=edit vim.

It must be done by our other plugin, because elixir-vim itself do not attempt to do any compilation (I bet that you are using either Syntastic or ALE and these are the source of the problem).