【发布时间】:2014-06-02 14:02:58
【问题描述】:
我正在尝试使用 seafile web api (https://github.com/haiwen/seafile/wiki/Seafile-web-API#upload-file) 从 c++ Qt5 代码上传文件。
API 与 curl 配合得很好,但使用 Qt 我从 apache 收到“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,但没有成功。
我在流量中提到的一个区别是,当我使用 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
这实际上不是我的主要域,所以我不确定我可以做些什么来进一步调试?
感谢任何提示,谢谢
【问题讨论】:
标签: c++ qt http curl network-programming