我正在尝试使用 QNetworkAccessManager 将 http 多部分上传到专用服务器。
多部分由描述上传数据的 JSON 部分组成。
数据从串行 QIODevice 中读取,该设备对数据进行加密。
这是创建多部分请求的代码:
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart metaPart;
metaPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
metaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"metadata\""));
metaPart.setBody(meta.toJson());
multiPart->append(metaPart);
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(fileFormat));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\""));
filePart.setBodyDevice(p_encDevice);
p_encDevice->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(filePart);
QNetworkAccessManager netMgr;
QScopedPointer<QNetworkReply> reply( netMgr.post(request, multiPart) );
multiPart->setParent(reply.data()); // delete the multiPart with the reply
如果 p_encDevice 是 QFile 的一个实例,那么该文件就可以正常上传。
如果使用专门的加密 QIODevice(串行设备),那么所有数据都是从我的自定义设备中读取的。但是 QNetworkAccessManager::post() 没有完成(挂起)。
我在QHttpPart的文档中读到:
如果设备是顺序的(例如套接字,但不是文件),则应该在设备发出完成()之后调用 QNetworkAccessManager::post()。
不幸的是,我不知道该怎么做。
请指教。
编辑:
QIODevice 根本没有finished() 插槽。更重要的是,如果没有调用 QNetworkAccessManager::post(),则根本不会从我的自定义 IODevice 中读取数据,因此设备将无法发出这样的事件。(第 22 条?)
编辑2:
QNAM 似乎根本不适用于顺序设备。请参阅关于 qt-project 的讨论。
编辑 3:
我设法“愚弄”了 QNAM,使其认为它正在从非顺序设备读取,但查找和重置功能阻止了查找。这将一直有效,直到 QNAM 真正尝试寻找。
bool AesDevice::isSequential() const
{
return false;
}
bool AesDevice::reset()
{
if (this->pos() != 0) {
return false;
}
return QIODevice::reset();
}
bool AesDevice::seek(qint64 pos)
{
if (this->pos() != pos) {
return false;
}
return QIODevice::seek(pos);
}