2013-12-03 5 views
2

Я начал лечить Erlang. Я хочу написать простой HTTP-сервер на основе ковбоя, который может получать файлы, отправляемые через HTTP POST. Поэтому я создаю простой обработчик:Cowboy HTTP POST handlers

-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. 

Этот код может обрабатывать запрос GET. Но как я могу обработать запрос HTTP POST?

+0

Обратите внимание на официальное приложение примера Cowboy - https://github.com/extend/cowboy/tree/master/examples/rest_pastebin. – mkorszun

ответ

7

Ваш код обрабатывает запросы любыми методами HTTP. Если вы хотите обрабатывать определенный метод HTTP-запроса, вам нужно проверить имя метода в дескрипторе обратного вызова/2. Здесь вы можете увидеть простой пример:

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}. 

Чтобы получить содержание POST запросить вы можете использовать функцию cowboy_req: body_qs/2, например. Существуют и другие функции для обработки тела HTTP-запросов в ковбои. Проверьте документацию и выберите способ, который вам удобен.

+0

Для всех, кто попадает по этой ссылке. Существует еще один способ, с помощью которого можно идентифицировать свой метод только внутри функции init(). Затем создайте другой метод, который представляет собой init()/(> = 3), который фактически соответствует шаблону в соответствии с методом, который внутренне может вызвать ваш метод дескриптора. Вам просто нужно вернуть соответствующий кортеж. –

0

Вы можете использовать cowboy_rest, реализовать content_types_accepted/2 метод обратного вызова следующим образом:

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. 

Я думаю, таким образом, вы можете иметь отдельные обработчики для различных HTTP Глаголы/Methods. Это дает вам чистый код тоже :)

и различные обработчики:

put_file(Req, State) -> 

    {true, Req, State}. 

post_file(Req, State) -> 

    {true, Req, State}. 
0

Вот ковбой промежуточного слоя, который будет добавлять метод обработчика:

т.е. ваш handler станет 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}. 
Смежные вопросы