I'm experimenting with multi-part form submissions for the purpose of uploading files to a web server. I adapted the following code from the sample found in the documentation for QHttpMultiPart:
QHttpMultiPart * pMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart1;
textPart1.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"Sport1\"");
textPart1.setBody("Dodgeball");
pMultiPart->append(textPart1);
QHttpPart textPart2;
textPart2.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"Sport2\"");
textPart2.setBody("Kickball");
pMultiPart->append(textPart2);
QNetworkRequest request(myUrl);
QNetworkReply * pReply = m_pNetworkManager->post(request, pMultiPart);
pMultiPart->setParent(pReply);
connect(pReply, SIGNAL(finished()), this, SLOT(replyFinished()));
The server keeps rejecting the submission with error 500. The problem is definitely not the script that is receiving the data as I have reduced it to simply return "Hello World" no matter what the request.
It seems that Qt (version 5.5) is doing something wrong with the boundary. I was able to get it to work by both setting the boundary to a string of my own choosing and by setting the header which specifies the boundary.
I added these two lines:
pMultiPart->setBoundary("---------------------jasglfuyqwreltjaslgjlkdaghflsdgh");
...
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + pMultiPart->boundary());
Here it is all together:
QHttpMultiPart * pMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
pMultiPart->setBoundary("---------------------jasglfuyqwreltjaslgjlkdaghflsdgh");
QHttpPart textPart1;
textPart1.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"Sport1\"");
textPart1.setBody("Dodgeball");
pMultiPart->append(textPart1);
QHttpPart textPart2;
textPart2.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"Sport2\"");
textPart2.setBody("Kickball");
pMultiPart->append(textPart2);
QNetworkRequest request(myUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + pMultiPart->boundary());
QNetworkReply * pReply = m_pNetworkManager->post(request, pMultiPart);
pMultiPart->setParent(pReply);
connect(pReply, SIGNAL(finished()), this, SLOT(replyFinished()));
Related
I am trying to make a post/get call using QNetworkAccessManager in my c++ code which is exposed to webassembly using emscripten.
When the exposed function is compiled and loaded in Javascript, the requests are getting blocked due to cross-origin request.
I am running the local server from the folder that contains wasm, js and html files.
[Edited]: After some reading on CORS, I tried by adding additional header parameters to request:
request.setRawHeader("Access-Control-Request-Origin", "*");
But this also didn't work.
QNetworkRequest request(this->server);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Access-Control-Allow-Origin", "*"); request.setRawHeader("Access-Control-Allow-Methods", "POST");
// building the json and network request object
QByteArray byte_payload = QJsonDocument(payload).toJson();
QEventLoop loop;
QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
loop.exec();
std::cout << "Request completed" << std::endl;
QByteArray reponse = reply->readAll();
std::cout << reponse.toStdString() << std:: endl;
Could you let me know how to resolve this?
[Edited]:
I tried to enable the node server for cros by using cors package. This enables the first OPTIONS call to succeed but the actual POST call that happens is send with incorrect payload.
I am confusing when I want to post a image file to server. With a clear post, I can just use QHttpMultiPart ,and it works fine. But this time I want to add some params, the server just don't get them.
I have searched for days , But no solution is found.
The code goes like this:
QUrl url("http://192.168.1.211/v1");
QUrlQuery query;
//following params are what i want to add
query.addQueryItem("app_name", "pc");
query.addQueryItem("ip", "192.168.1.110");
query.addQueryItem("dev_os","android");
query.addQueryItem("dev_os_ver","11.4.1");
query.addQueryItem("dev_model",testEquip);
query.addQueryItem("latitude","23.137466");
query.addQueryItem("longitude","113.352425");
query.addQueryItem("user_id","1");
query.addQueryItem("nickname","nick");
query.addQueryItem("sex","1");
query.addQueryItem("headimgurl","http://some.com/");
url.setQuery(query);
QNetworkRequest req;
req.setUrl(url);
req.setRawHeader("X-Api-Key","JDZBNH3HDFI823AISDU9SF32IRJ");
QHttpMultiPart *multiPart=new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"image\"; filename=\""+filename+"\""));
QFile *file=new QFile(path);
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
file->setParent(multiPart);
multiPart->append(imagePart);
QNetworkAccessManager *manager=new QNetworkAccessManager();
QNetworkReply *reply=manager->post(req,multiPart);
multiPart->setParent(reply);
The response code shows no params have been accessed. So what is the right way to add these params?
Using Qt 5.4 32-bit on Windows 8.1 (64-bit) with MingW.
I am experiencing a weird problem. Consider this:
//QString m_sUrl = "cloud.mysystem.info/";
//QString m_sFileName = "results.html";
//QNetworkAccessManager m_Manager;
QUrl url(m_sURL + m_sFileName);
url.setScheme("ftp");
url.setUserName(m_sLogin);
url.setPassword(m_sPassword);
QFile *file = new QFile(m_sFileName);
if(file->open(QIODevice::ReadOnly))
{
QNetworkReply *reply = m_Manager.put(QNetworkRequest(url), file);
connect(reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, &OCMResults::error);
connect(reply, &QNetworkReply::finished, reply, &QObject::deleteLater);
connect(reply, &QNetworkReply::finished, file, &QObject::deleteLater);
}
else
file->deleteLater();
At first my code worked fine but then it stopped working (possibly due to my change, not sure what was it) and only workaround is when I write the url explicitely:
QNetworkReply(QUrl("ftp://" + m_sLogin + ":" + m_sPassword + "#" + m_sURL + m_sFileName)), file);
The resulting URL is exactly the same but for some reason when I create it beforehand and pass it to the QNetworkReply it does not take it:
reply.url().host()
yields nothing if that is the case for example. I feel like I am missing something really obvious here...
The errors are either:
3 (host not found) when ftp is specified in the url string
301 (unknown protocol) when I do not specify it in the url but specify it as setScheme("ftp") instead
Thanks!
I hava a problem of uploading .txt file to my java servlet server using Qt.
I spent 5 days on that and tried a lot of solutions. But none of them worked. Does anyone can help me?
The problem is that the Qt code can work without error. But the server didn't receive anything by the httprequest from Qt.
This is one solution in Qt:
QFile file("dataToSend.txt");
nam = new QNetworkAccessManager(this);
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
QNetworkRequest r(QUrl("http://localhost:9999/server"));
QString bound="---------------------------723690991551375881941828858";
QByteArray data(QString("--"+bound+"\r\n").toAscii());
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"file\"; filename=\""+file.fileName()+"\"\r\n";
data += "Content-Type: text/plain\r\n\r\n";
file.open(QIODevice::ReadOnly);
data += file.readAll();
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
r.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
r.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());
reply = nam->post(r,data);
reply=nam->get(r);
This is another solution, it is not wokring neither:
nam = new QNetworkAccessManager(this);
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
QFile *file=new QFile("dataToSend.txt");
QNetworkRequest request(QUrl("http://localhost:9999/server"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-streamd");
if(!file->open(QIODevice::ReadOnly)){
qDebug("%s\n",qPrintable("can't open the file!"));
return;
}
// post data to server
reply= nam->post(request,file);
file->setParent(reply);
reply=nam->get(request);
you cannot post() something to a server and a line below do a get() expecting to see the file.
Usually you have to post, wait until post is finished, and than you can see modification..
here there are lots of link you can use to do things right
i am developing a simple application which uploads image to yfrog.com.(These images will be reflected in twitter account). Here is my code. but it is not working. I am not getting response from server.
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest request(QUrl("http://yfrog.com/api/uploadAndPost"));
QByteArray data;
QUrl params,params1;
QFile file("some image path");
QString boundary("-----abcde12345");
QString body = "\r\n--" + boundary + "\r\n";
params.addQueryItem("username",twitterusername);
params.addQueryItem("password",twitterpassword);
params.addQueryItem("message",some message...);
params.addQueryItem("key",mydeveloperkey);
data.append(body);
data.append(params.toString());
QByteArray ba;
ba=file.readAll();
QString body1(ba);
params1.addQueryItem("media",body1);
data.append(params1.toString());
data.append(body);
request.setRawHeader("Content-Type","multipart/form-data; boundary=-----abcde12345");
request.setHeader(QNetworkRequest::ContentLengthHe ader,data.size());
QNetworkReply *reply = manager->post(request,data);
reply->waitForReadyRead(-1);
qDebug() << "replay :"<<reply->readAll();
If i checked the requested TCP packets from wireshark, it is giving a error message like 'malformed packets'.
For reference : http://code.google.com/p/imageshacka...GuploadAndPost
Please any body help regarding this. Where i am doing wrong?
QNetworkReply::waitForReadyRead does not have an implementation so it always refers the base class waitForReadyRead() (in this case QIODevice). In the base class, you will see that waitForReadyRead always returns FALSE.
From the docs, you would have to instead use the readRead() signal in QNetworkReply and read the data when the slot is called.
QNetworkReply *reply = manager->get(request);
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));