我尝试使用seafile web api(https://github.com/haiwen/seafile/wiki/Seafile-web-API#upload-file)从c ++ Qt5代码上传文件。
API与curl配合得很好,但是对于Qt,我得到了一个" 400 Bad Request"来自阿帕奇。
我使用wireshark来查看请求中的差异。卷曲:
curl -k -F "file=@/tmp/test_up.txt; filename=qt.txt" -F parent_dir=/ myserver.com/seafhttp/upload-api/f8e70ecc
给了我
POST /seafhttp/upload-api/f8e70ecc HTTP/1.1
User-Agent: curl/7.37.0
Host: myserver.com
Accept: */*
Content-Length: 292
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------9a2b257b2a34c31f
--------------------------9a2b257b2a34c31f
Content-Disposition: form-data; name="file"; filename="qt.txt"
Content-Type: text/plain
test up
--------------------------9a2b257b2a34c31f
Content-Disposition: form-data; name="parent_dir"
/
--------------------------9a2b257b2a34c31f--
现在是Qt来源:
QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart file_part;
file_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"qt.txt\"")); //
file_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
QFile *file = new QFile{"/tmp/test_up.txt"};
file->open(QIODevice::ReadOnly);
file_part.setBodyDevice(file);
file->setParent(multipart); // we cannot delete the file now, so delete it with the multipart
QHttpPart parent_dir_part;
parent_dir_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"parent_dir\""));
parent_dir_part.setBody("/");
multipart->append(file_part);
multipart->append(parent_dir_part);
QNetworkRequest request{server + upload_url};
_reply = _manager.post(request, multipart);
multipart->setParent(_reply); // delete the multipart with the reply
给了我
POST /seafhttp/upload-api/f8e70ecc HTTP/1.1
Content-Type: multipart/form-data; boundary="boundary_.oOo._MTgzMTcwMjYyNg==MTc3NDExNzExNg==NTI2MDQyOTI1"
MIME-Version: 1.0
Content-Length: 349
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,en,*
User-Agent: Mozilla/5.0
Host: myserver.com
--boundary_.oOo._MTgzMTcwMjYyNg==MTc3NDExNzExNg==NTI2MDQyOTI1
Content-Disposition: form-data; name="file"; filename="qt.txt"
Content-Type: text/plain
test up
--boundary_.oOo._MTgzMTcwMjYyNg==MTc3NDExNzExNg==NTI2MDQyOTI1
Content-Disposition: form-data; name="parent_dir"
/
--boundary_.oOo._MTgzMTcwMjYyNg==MTc3NDExNzExNg==NTI2MDQyOTI1--
服务器端我有两个请求的这些日志:
myserver.com - - [02/Jun/2014:15:20:18 +0200] "POST /seafhttp/upload-api/f8e70ecc HTTP/1.1" 200 166 "-" "curl/7.37.0"
myserver.com - - [02/Jun/2014:15:21:28 +0200] "POST /seafhttp/upload-api/f8e70ecc HTTP/1.1" 400 103 "-" "Mozilla/5.0"
现在这两个请求似乎非常接近,我在Qt代码中没有使用任何花哨的东西,遵循QHttpMultiPart文档示例。 我尝试更改UserAgent或边界以更接近卷曲,但没有成功。
我在流量中评论的一个区别是,当我使用curl时,它会等待"继续"在发送其余数据之前:
[TCP segment of a reassembled PDU]
[ACK]
HTTP/1.1 100 Continue
[ACK]
[TCP segment of a reassembled PDU]
[ACK]
POST /seafhttp/upload-api/f8e70ecc HTTP/1.1 (text/plain)
[ACK]
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
而Qt则是这样的:
[TCP segment of a reassembled PDU]
[ACK]
POST /seafhttp/upload-api/f8e70ecc HTTP/1.1 (text/plain)
[ACK]
HTTP/1.1 400 Bad Request
这不是我的主要域名,所以我不确定我可以做些什么来进一步调试?
任何提示都表示赞赏,谢谢
答案 0 :(得分:0)
确定手动重写请求后直到它工作我找到了解决方案。这似乎是一个错误服务器端。
Qt在标题中的边界声明周围添加双引号,这似乎与rfc有关(请参阅此处的封闭错误:https://bugreports.qt-project.org/browse/QTBUG-29744)。
无论如何,解决方法很简单,我只是重写了没有引号的标题:
request.setRawHeader("Content-Type", "multipart/form-data; boundary=" + multipart->boundary());