无法在响应钩子中获取请求体

时间:2013-10-22 12:11:03

标签: erlang cowboy

我想记录所有请求以及对db的响应。我正在使用钩子。但看起来我无法在'onresponse'钩子中获取请求体,它总是<<>>。在'onrequest'钩子我可以得到请求体。

我的钩子定义为:

request_hook(Req) ->
   %% All is OK: ReqBody contains what I sent:
   {ok, ReqBody, Req2} = cowboy_req:body(Req),
   io:format("request_hook: body = ~p", [ReqBody]),
   Req2.

response_hook(_Status, _Headers, _Body, Req) ->
   %% ReqBody is always <<>> at this point. Why?
   {ok, ReqBody, Req2} = cowboy_req:body(Req),
   io:format("response_hook: body = ~p", [ReqBody]),
   Req2.

这是牛仔或正常行为的错误吗?

我正在使用写这篇文章时提供的最新牛仔(提交:aab63d605c595d8d0cd33646d13942d6cb372b60)。

1 个答案:

答案 0 :(得分:1)

最新版本的Cowboy(我从v0.8.2中了解到)使用以下方法来提高性能 - cowboy_req:body(Req)返回Body和NewReq结构而不需要请求体。换句话说,这是一种正常行为,您只能检索一次请求正文。 牛仔没有收到请求体,因为它可能是巨大的,身体放在插座中,直到它变得必要(直到cowboy_req:body/1电话)。 检索正文后,它在处理程序中也不可用。 因此,如果您想在处理程序中实现日志记录并使主体可用,您可以根据请求将正文保存到共享位置,并在响应时显式删除它。

request_hook(Req) ->
        %% limit max body length for security reasons
        %% here we expects that body less than 80000 bytes
        {ok, Body, Req2} = cowboy_req:body(80000, Req),
        put(req_body, Body), %% put body to process dict 
        Req2.

response_hook(RespCode, RespHeaders, RespBody, Req) ->
        ReqBody = get(req_body),
        Req2.

%% Need to cleanup body record in proc dict
%% since cowboy uses one process per several
%% requests in keepalive mode
terminate(_Reason, _Req, _St) ->
        put(req_body, undefined),                
        ok.