为什么 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。