为什么 Ejabberd 以不同的方式处理 PUT 和 POST 请求?
Why is Ejabberd handling PUT and POST requests differently?
当 PUT 的主体大于特定长度(在我的例子中是 902 字节)时,这似乎会导致奇怪的行为,即 ejabberd 修剪主体(在我的例子中它收到格式错误 JSON)。
Github参考:https://github.com/processone/ejabberd/blob/master/src/ejabberd_http.erl#L403
如果我将 case 语句更改为:
case Method of
_AnyMethod ->
case recv_data(State) of
{ok, Data} ->
LQuery = case catch parse_urlencoded(Data) of
{'EXIT', _Reason} -> [];
LQ -> LQ
end,
{State, {LPath, LQuery, Data}};
error ->
{State, false}
end
end
那么正文就被正确解析了。
这是配置问题吗?如何强制 Ejabberd 正确解析 JSON 正文?
看来您发现了一个错误。
如您所见,对于 POST 请求,函数 recv_data
被调用,它检查 Content-Length header 并从套接字读取那么多字节。然而,对于 PUT 请求,它只使用 Trail
,这是在读取 HTTP 请求 header 时已经收到的数据。 (这发生在 receive_headers
函数中,它向 recv
函数发送长度为 0,这意味着它不会等待任何特定数量的数据。)
收到多少请求 body 取决于 header 的大小,以及客户端发送请求的方式。例如,如果客户端首先在一个网络数据包中发送 headers,然后在下一个网络数据包中发送请求 body,则 ejabberd 根本不会接收请求 body。
当 PUT 的主体大于特定长度(在我的例子中是 902 字节)时,这似乎会导致奇怪的行为,即 ejabberd 修剪主体(在我的例子中它收到格式错误 JSON)。
Github参考:https://github.com/processone/ejabberd/blob/master/src/ejabberd_http.erl#L403
如果我将 case 语句更改为:
case Method of
_AnyMethod ->
case recv_data(State) of
{ok, Data} ->
LQuery = case catch parse_urlencoded(Data) of
{'EXIT', _Reason} -> [];
LQ -> LQ
end,
{State, {LPath, LQuery, Data}};
error ->
{State, false}
end
end
那么正文就被正确解析了。
这是配置问题吗?如何强制 Ejabberd 正确解析 JSON 正文?
看来您发现了一个错误。
如您所见,对于 POST 请求,函数 recv_data
被调用,它检查 Content-Length header 并从套接字读取那么多字节。然而,对于 PUT 请求,它只使用 Trail
,这是在读取 HTTP 请求 header 时已经收到的数据。 (这发生在 receive_headers
函数中,它向 recv
函数发送长度为 0,这意味着它不会等待任何特定数量的数据。)
收到多少请求 body 取决于 header 的大小,以及客户端发送请求的方式。例如,如果客户端首先在一个网络数据包中发送 headers,然后在下一个网络数据包中发送请求 body,则 ejabberd 根本不会接收请求 body。