为什么使用 SSL 和 POCO returns 状态 411 发送多部分表单数据?

Why Sending multi-part form data using SSL & POCO returns status 411?

我已经编写了一个使用 JIRA Service Desk 的界面 API。我实现的 REST API 调用之一执行 multipart/form-data 的 HTTP POST。这在我使用 HTTP 时工作正常,但是当我使用 HTTPS 时,我得到一个 411 Length Required 响应。

当我使用 curl 或 postman 时,REST API 调用命令在 HTTPS 上工作正常。

使用 HTTPS 时我是否遗漏了什么?

我的表格post代码如下:

// generic form send
RESTClient::Error RESTClient::HTTPFormSend(
    const std::string & method,
    const std::string & command,
    const Params & headerParams,
    Poco::Net::HTMLForm & form,
    HTTPRequestSetup requestFunc
)
{
    Error ret = Error::None;

    try
    {
        Poco::Net::HTTPRequest request;

        Poco::SharedPtr<Poco::Net::HTTPClientSession> pSession(PrepareSession(method, command, headerParams, request));

        Poco::Net::HTTPResponse httpResponse;

        // authenticate
        m_credentials.authenticate(request);

        // custom request setup    
        if (requestFunc)
            requestFunc(request);

        if (!DoFormRequest(pSession, request, httpResponse, form))
        {
            m_credentials.authenticate(request);

            if (!DoFormRequest(pSession, request, httpResponse, form))
            {
                m_logger.error("Invalid username or password");
            }
        }
    }
    catch (const Poco::Exception &ex)
    {
        m_logger.error(ex.displayText());
        ret = Error::Internal;
    }

    return ret;
}

// send form
bool RESTClient::DoFormRequest(
    Poco::Net::HTTPClientSession *pSession,
    Poco::Net::HTTPRequest & request,
    Poco::Net::HTTPResponse & response,
    Poco::Net::HTMLForm &form
)
{
    Poco::LogStream logStream(m_logger);

    form.prepareSubmit(request);

    pSession->setTimeout(Poco::Timespan(20, 0));

    form.write(pSession->sendRequest(request));

    return ProcessResponse(pSession, response);
}

Poco::Net::HTMLForm::prepareSubmit() 在提交多部分表单时通常会使用 Chunked Transfer-Encoding,因此不会设置 Content-Length header。作为解决方法,您可以尝试在调用 prepareSubmit() 之前将请求的 HTTP 版本设置为 1.0。这将强制 prepareSubmit() 计算长度并设置 Content-Length header,而不是使用分块传输编码。调用prepareSubmit()后,可以将HTTP版本重置为1.1。

request.setVersion(Poco::Net::HTTPMessage::HTTP_1_0);
form.prepareSubmit(request);
request.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);