使用 POST 上传大文件会冻结系统
Uploading big files with POST freezes the system
我有一个使用标准 post 请求将文件(视频文件)上传到服务器的应用程序,例如:
QNetworkRequest request(QUrl("myUrl"));
QString bound="margin";
QByteArray data(QString("--"+bound+"\r\n").toLatin1());
data += "Content-Disposition: form-data; name=\"media_id\"\r\n\r\n";
data += id + "\r\n";
data += QString("--" + bound + "\r\n").toLatin1();
QString str = "Content-Disposition: form-data; name=\"file\"; filename=\"" + name + "\r\n";
data += str;
data += "Content-Type: video/mp4\r\n\r\n";
QFile f(path);
if(! f.open(QIODevice::ReadOnly))
{
qDebug() << "uploadMediaRequest error opening " << path;
return false;
}
QByteArray bytes;
bytes = f.readAll();
data.append(bytes);
data += "\r\n";
data += QString("--" + bound + "\r\n.").toLatin1();
data += "\r\n";
f.close();
request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());
request.setRawHeader(QString("Content-Type").toLatin1(),QString("multipart/form-data; boundary=" + bound).toLatin1());
request.setRawHeader(QString("Content-Length").toLatin1(), QString::number(data.length()).toLatin1());
然后 POST 该请求。
对于 1GB 或更少的文件,它工作得很好,但如果我尝试上传 1.5GB 的文件,我得到
myProgramName[948:32028] Communications error: <OS_xpc_error: <error: 0x7fff7c37bb60> { count = 1, contents =
"XPCErrorDescription" => <string: 0x7fff7c37bfa8> { length = 22, contents = "Connection interrupted" }}>
Got xpc error message: Connection interrupted
应用程序和 SO 冻死了。
我想我可以拆分大文件并将它们分成几部分上传并制作服务器 assemble 但我想知道你们中是否有人可以给我解释这个奇怪的错误。
我使用 OSX 和 Qt 5.4,提前谢谢!
由用户 Pavel Strakhov 解决:
QNetworkRequest request(QUrl("myUrl"));
QFile *f = new QFile(path);
if(! f->open(QIODevice::ReadOnly))
{
qDebug() << "uploadMediaRequest error opening " << path;
return false;
}
QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart idPart, mediaPart;
idPart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"media_id\""));
idPart.setBody(id.toLatin1());
mediaPart.setHeader(QNetworkRequest::ContentTypeHeader, type);
mediaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+ name + "\""));
mediaPart.setBodyDevice(f);
f->setParent(multiPart);
multiPart->append(idPart);
multiPart->append(mediaPart);
request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());
networkManager->post(request, multiPart));
现在运行良好。
我有一个使用标准 post 请求将文件(视频文件)上传到服务器的应用程序,例如:
QNetworkRequest request(QUrl("myUrl"));
QString bound="margin";
QByteArray data(QString("--"+bound+"\r\n").toLatin1());
data += "Content-Disposition: form-data; name=\"media_id\"\r\n\r\n";
data += id + "\r\n";
data += QString("--" + bound + "\r\n").toLatin1();
QString str = "Content-Disposition: form-data; name=\"file\"; filename=\"" + name + "\r\n";
data += str;
data += "Content-Type: video/mp4\r\n\r\n";
QFile f(path);
if(! f.open(QIODevice::ReadOnly))
{
qDebug() << "uploadMediaRequest error opening " << path;
return false;
}
QByteArray bytes;
bytes = f.readAll();
data.append(bytes);
data += "\r\n";
data += QString("--" + bound + "\r\n.").toLatin1();
data += "\r\n";
f.close();
request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());
request.setRawHeader(QString("Content-Type").toLatin1(),QString("multipart/form-data; boundary=" + bound).toLatin1());
request.setRawHeader(QString("Content-Length").toLatin1(), QString::number(data.length()).toLatin1());
然后 POST 该请求。 对于 1GB 或更少的文件,它工作得很好,但如果我尝试上传 1.5GB 的文件,我得到
myProgramName[948:32028] Communications error: <OS_xpc_error: <error: 0x7fff7c37bb60> { count = 1, contents =
"XPCErrorDescription" => <string: 0x7fff7c37bfa8> { length = 22, contents = "Connection interrupted" }}>
Got xpc error message: Connection interrupted
应用程序和 SO 冻死了。 我想我可以拆分大文件并将它们分成几部分上传并制作服务器 assemble 但我想知道你们中是否有人可以给我解释这个奇怪的错误。
我使用 OSX 和 Qt 5.4,提前谢谢!
由用户 Pavel Strakhov 解决:
QNetworkRequest request(QUrl("myUrl"));
QFile *f = new QFile(path);
if(! f->open(QIODevice::ReadOnly))
{
qDebug() << "uploadMediaRequest error opening " << path;
return false;
}
QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart idPart, mediaPart;
idPart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"media_id\""));
idPart.setBody(id.toLatin1());
mediaPart.setHeader(QNetworkRequest::ContentTypeHeader, type);
mediaPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\""+ name + "\""));
mediaPart.setBodyDevice(f);
f->setParent(multiPart);
multiPart->append(idPart);
multiPart->append(mediaPart);
request.setRawHeader(QString("Accept").toLatin1(),QString("application/json, text/javascript, */*; q=0.01").toLatin1());
request.setRawHeader(QString("Origin").toLatin1(),QString("http://dev.teamhood.io").toLatin1());
request.setRawHeader(QString("API-Client").toLatin1(),QString("desktop").toLatin1());
request.setRawHeader(QString("withCredentials").toLatin1(), QString("true").toLatin1());
networkManager->post(request, multiPart));
现在运行良好。