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