0

我想记录所有请求以及对 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)。

4

1 回答 1

1

最新版本的 Cowboy(据我所知,从 v0.8.2 开始)使用以下方法来提高性能 -cowboy_req:body(Req)返回 Body 和 NewReq 结构而无需请求正文。换句话说,这是一种正常行为,您只能检索一次请求正文。Cowboy 不会收到请求主体,因为它可能很大,主体放置在套接字中,直到需要(直到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.                                        
于 2013-11-05T04:43:42.530 回答