[Cowboy-Erlang]: Error when pin-pointing to localhost:8080 using provided cowboy example web_server

612 views Asked by At

I am trying out a cowboy example provided by this github repository:

https://github.com/ninenines/cowboy/tree/master/examples/web_server

I build the release successfully using erlang.mk and run the following command, which opens the Erlang shell in my linux terminal:

$ ./_rel/web_server_example/bin/web_server_example console

But when I then open http://localhost:8080 in my web-browser, I get the following error report:

=ERROR REPORT==== 26-Nov-2014::14:33:48 === Error in process <0.166.0> on node '[email protected]' with exit value: {function_clause,[{cowboy_req,ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<3 bytes>>,'HTTP/1.1',{{127,0,0,1},57150},<<9 bytes>>,undefined,8080,<<1 byte>>,undefined,<<0 bytes>>,undefined,undefined,[{<<4 bytes>>,<<14 bytes>>},{<<10 bytes>>,<<10 bytes>>},{<<13 bytes>>,<<9 bytes>>},{<<6 bytes>>,<<74 bytes>>},{<<10 bytes>>,<<104 bytes>>},{<<15 bytes>>,<<19 bytes>>},{<<15 bytes>>,<<35 bytes>>}],[{<<10 bytes>>,[<<10 bytes>>]}],undefined,[],waiting,<<0 bytes>>,undefined...

=ERROR REPORT==== 26-Nov-2014::14:33:48 === Ranch listener http had connection process started with cowboy_protocol:start_link/4 at <0.166.0> exit with reason: {function_clause,[{cowboy_req,ensure_response,[{ok,{http_req,#Port<0.454>,ranch_tcp,keepalive,<0.166.0>,<<"GET">>,'HTTP/1.1',{{127,0,0,1},57150},<<"localhost">>,undefined,8080,<<"/">>,undefined,<<>>,undefined,undefined,[{<<"host">>,<<"localhost:8080">>},{<<"connection">>,<<"keep-alive">>},{<<"cache-control">>,<<"max-age=0">>},{<<"accept">>,<<"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8">>},{<<"user-agent">>,<<"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36">>},{<<"accept-encoding">>,<<"gzip, deflate, sdch">>},{<<"accept-language">>,<<"sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4">>}],[{<<"connection">>,[<<"keep-alive">>]}],undefined,[],waiting,<<>>,undefined,false,done,[],<<>>,undefined}},204],[{file,"src/cowboy_req.erl"},{line,1009}]},{cowboy_protocol,next_request,3,[{file,"src/cowboy_protocol.erl"},{line,454}]}]}

This is "src/cowboy_protocol.erl" around line 454:

-spec next_request(cowboy_req:req(), #state{}, any()) -> ok.
next_request(Req, State=#state{req_keepalive=Keepalive, timeout=Timeout},
        HandlerRes) ->
    cowboy_req:ensure_response(Req, 204),
    %% If we are going to close the connection,
    %% we do not want to attempt to skip the body.
    case cowboy_req:get(connection, Req) of
        close ->
            terminate(State);
        _ ->
            %% Skip the body if it is reasonably sized. Close otherwise.
            Buffer = case cowboy_req:body(Req) of
                {ok, _, Req2} -> cowboy_req:get(buffer, Req2);
                _ -> close
            end,
            %% Flush the resp_sent message before moving on.
            if HandlerRes =:= ok, Buffer =/= close ->
                    receive {cowboy_req, resp_sent} -> ok after 0 -> ok end,
                    ?MODULE:parse_request(Buffer,
                        State#state{req_keepalive=Keepalive + 1,
                        until=until(Timeout)}, 0);
                true ->
                    terminate(State)
            end
    end.

And the webb_server_app.erl file:

%% Feel free to use, reuse and abuse the code in this file.

%% @private
-module(web_server_app).
-behaviour(application).

%% API.
-export([start/2]).
-export([stop/1]).

%% API.

start(_Type, _Args) ->
    Dispatch = cowboy_router:compile([
        {'_', [
            {"/[...]", cowboy_static, {priv_dir, web_server, "", [
                {mimetypes, cow_mimetypes, all},
                {dir_handler, directory_handler}
            ]}}
        ]}
    ]),
    {ok, _} = cowboy:start_http(http, 100, [{port, 8080}], [
        {env, [{dispatch, Dispatch}]},
        {middlewares, [cowboy_router, directory_lister, cowboy_handler]}
    ]),
    web_server_sup:start_link().

stop(_State) ->
    ok.

Does anyone have any suggestion as to what is exactly causing this problem, and how to solve it? Thanks.

EDIT:

I can confirm that the fault was in the Erlang OTP version R16B02 in my case. Changing to the latest Erlang release (17.3), as well as resolving missing file dependencies that arose during the configuration stage (with the solutions in the following link):

https://sites.google.com/site/comptekkia/erlang/how-to-install-erlang-on-ubuntu-10-10

Solved the problem(s). The web_server example runs without error now.

1

There are 1 answers

3
tkowal On BEST ANSWER

The error says function clause, so the arguments to cowboy_req:ensure_response/2 must be wrong. And indeed they are, because first argument is {ok, Request} instead of Request. You have to trace back, which function called next_request/3 with bad argument, because it clearly should be called without ok.

Probably somewhere at the end, you will find something like:

Req = some_function(...)

And you will need to change it to:

{ok, Req} = some_function(...)

Good luck and happy bug hunting :D

UPDATE: I just cloned the repo and it works fine for me. I got the directory listing, so it is not bug in cowboy, but somewhere in user code.