2
votes

Trying to receive the POST request and store it into ETS table

here is the code

init(Req0, Opts) ->
    Method = cowboy_req:method(Req0),
    HasBody = cowboy_req:has_body(Req0),
    Req = maybe_echo(Method, HasBody, Req0),
    {ok, Req, Opts}.

maybe_echo(<<"POST">>, true, Req0) ->
    {ok, PostVals, Req} = cowboy_req:read_urlencoded_body(Req0),
    Echo = proplists:get_value(<<"echo">>, PostVals),
    echo(Echo, Req);

maybe_echo(<<"POST">>, false, Req) ->
    cowboy_req:reply(400, [], <<"Missing body.">>, Req);

maybe_echo(_, _, Req) ->
    %% Method not allowed.
    cowboy_req:reply(405, Req).

echo(undefined, Req) ->
    cowboy_req:reply(400, [], <<"Missing echo parameter.">>, Req);

echo(Echo, Req) ->
Inf = #news{id=25, created=today, article=Echo},
    case ets:insert(news, {Inf#news.id, Inf#news.created, Inf#news.article}) of
        true -> cowboy_req:reply(200, #{<<"content-type">> => <<"text/plain; charset=utf-8">>}, Echo, Req);
        _        -> 
            Error = <<"{\"error\": \"error\"}">>,
            cowboy_req:reply(200, #{<<"content-type">> => <<"text/plain; charset=utf-8">>}, Error, Req)
    end.

when i curl :

$ curl -i -H "Content-Type: application/json" -X POST -d echo='{"action":"insert","key":"some_key", "value":[1,2,3]}' http://localhost:8080/

I'm getting the error:

=ERROR REPORT==== 29-Jan-2017::18:57:21 === Ranch listener http, connection process <0.240.0>, stream 1 had its request process <0.241.0> exit with reason badarg and stacktrace [{ets,insert,[news,{25,today,<<"{\"action\":\"insert\",\"key\":\"some_key\", \"value\":[1,2,3]}">>}],[]},{post_handler,echo,2,[{file,"e:/_dev/news/_build/default/lib/news/src/post_handler.erl"},{line,25}]},{post_handler,init,2,[{file,"e:/_dev/news/_build/default/lib/news/src/post_handler.erl"},{line,8}]},{cowboy_handler,execute,2,[{file,"e:/_dev/news/_build/default/lib/cowboy/src/cowboy_handler.erl"},{line,39}]},{cowboy_stream_h,execute,3,[{file,"e:/_dev/news/_build/default/lib/cowboy/src/cowboy_stream_h.erl"},{line,173}]},{cowboy_stream_h,proc_lib_hack,3,[{file,"e:/_dev/news/_build/default/lib/cowboy/src/cowboy_stream_h.erl"},{line,158}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]

but when I use echo like this:

echo(Echo, Req) ->
    cowboy_req:reply(200, #{<<"content-type">> => <<"text/plain; charset=utf-8">>}, Echo, Req)
        end.

I receive the request - ({"action":"insert","key":"some_key", "value":[1,2,3]})

so seems like there is something with ETS? but I have no idea where I messed up

Creating ets in other module

ets:new(news, [ordered_set, protected, named_table, {keypos,1}, {read_concurrency, true}, {write_concurrency, true}])

could you please show me the right dirrection to resolve this issue

1
How/where are you creating the ETS table? Are you sure it's a named_table and the name is news? - Dogbert
@Dogbert I've created it in start module like this -record(news, {id, created, article}). Tab = ets:new(news, [ordered_set, protected, named_table, {keypos,1}, {read_concurrency, true}, {write_concurrency, true}]), {ok, Tab}. - Eugen Dubrovin
@Qbeck, you should edit that into the question. - Roger Lipscombe

1 Answers

3
votes

The protected option in the ets:new call means that only the process creating the ETS table will be allowed to insert data. Other processes can only read the data.

Use public instead and all processes will have read/write access.