Reputation: 391
I'm started learing Erlang. I want to write simple cowboy-based HTTP server, which can receive files sending via HTTP POST. So I create simple handler:
-module(handler).
-behaviour(cowboy_http_handler).
-export([init/3,handle/2,terminate/3]).
init({tcp, http}, Req, _Opts) ->
{ok, Req, undefined_state}.
handle(Req, State) ->
Body = <<"<h1>Test</h1>">>,
{ok, Req2} = cowboy_req:reply(200, [], Body, Req),
{ok, Req2, State}.
terminate(_Reason, _Req, _State) ->
ok.
This code can handle GET request. But how can I process HTTP POST request?
Upvotes: 3
Views: 5766
Reputation: 153
Here is a cowboy middleware that will append the method to your handler:
i.e. your handler
will become handler_post
-module(middleware).
-export([execute/2]).
execute(Req0, Env0) ->
{Method0, Req} = cowboy_req:method(Req0),
Method1 = string:lowercase(Method0),
Handler0 = proplists:get_value(handler, Env0),
Handler = list_to_atom(atom_to_list(Handler0) ++ "_" ++ binary_to_list(Method1)),
Env = [{handler, Handler} | proplists:delete(handler, Env0)],
{ok, Req, Env}.
Upvotes: 0
Reputation: 2020
You can use cowboy_rest, implement the content_types_accepted/2 callback method like so:
content_types_accepted(Req, State) ->
case cowboy_req:method(Req) of
{<<"POST">>, _ } ->
Accepted = {[{<<"application/x-www-form-urlencoded">>, put_file}], Req, State};
{<<"PUT">>, _ } ->
Accepted = {[{<<"application/x-www-form-urlencoded">>, post_file}], Req, State}
end,
Accepted.
I think this way you can have separate handlers for different HTTP Verbs/Methods. This gives you cleaner code too :)
And the various handlers:
put_file(Req, State) ->
{true, Req, State}.
post_file(Req, State) ->
{true, Req, State}.
Upvotes: 0
Reputation: 2040
Your code handles requests with any HTTP methods. If you want to handle particular HTTP request method you have to test the method name in callback handle/2. Here you can see a simple example:
handle(Req, State) ->
{Method, Req2} = cowboy_req:method(Req),
case Method of
<<"POST">> ->
Body = <<"<h1>This is a response for POST</h1>">>;
<<"GET">> ->
Body = <<"<h1>This is a response for GET</h1>">>;
_ ->
Body = <<"<h1>This is a response for other methods</h1>">>
end,
{ok, Req3} = cowboy_req:reply(200, [], Body, Req2),
{ok, Req3, State}.
To get a content of POST request you can use function cowboy_req:body_qs/2 for example. There are other functions for handling body of HTTP requests in cowboy. Check the documentation and choose the way which is convenient for you.
Upvotes: 8
Reputation: 580
You can work with 'cowboy_rest' for example: https://github.com/extend/cowboy/blob/master/examples/rest_pastebin/src/toppage_handler.erl
It gives you a more structured way to handle requests.
More info: http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_rest/
Upvotes: 0