为什么使用 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);
我已经编写了一个使用 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);