【问题标题】:Cowboy HTTP POST handlers牛仔 HTTP POST 处理程序
【发布时间】:2013-12-19 07:33:22
【问题描述】:

我开始学习 Erlang。我想写一个简单的基于牛仔的 HTTP 服务器,它可以接收通过 HTTP POST 发送的文件。所以我创建了简单的处理程序:

-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 请求?

【问题讨论】:

标签: erlang cowboy


【解决方案1】:

这是一个牛仔中间件,它将方法附加到您的处理程序:

即你的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}.

【讨论】:

    【解决方案2】:

    你可以使用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 动词/方法设置单独的处理程序。这也为您提供了更简洁的代码:)

    以及各种处理程序:

    put_file(Req, State) ->
    
      {true, Req, State}.
    
    post_file(Req, State) ->
    
      {true, Req, State}.
    

    【讨论】:

      【解决方案3】:

      您的代码使用任何 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 例如。在cowboy 中还有其他处理HTTP 请求主体的函数。查看文档并选择适合您的方式。

      【讨论】:

      • 对于任何点击此链接的人。还有另一种方法可以仅在 init() 函数中识别您的方法。然后根据内部可以调用您的句柄方法的方法设计另一种方法,即 init()/(>=3) 实际匹配模式。你只需要返回一个合适的元组。
      【解决方案4】:

      您可以使用“cowboy_rest”,例如:https://github.com/extend/cowboy/blob/master/examples/rest_pastebin/src/toppage_handler.erl

      它为您提供了一种更结构化的方式来处理请求。

      更多信息:http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_rest/

      【讨论】:

        猜你喜欢
        • 2017-06-14
        • 2017-06-22
        • 2015-04-18
        • 1970-01-01
        • 2013-05-30
        • 2017-11-29
        • 1970-01-01
        • 2018-08-28
        • 2020-09-28
        相关资源
        最近更新 更多