简体   繁体   中英

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

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 'web_server_example@127.0.0.1' 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_protoc ol,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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM