Put request in Qt using QNetworkAccessManager
I am writing an iPhone app in Qt Creator to do a Put request using the QNetworkAccessManager class. The request is sent to RESTful endpoint. I have python code that accomplishes what I need but for a different type of device so I'm just trying to do the same thing in C++ in Qt Creator. I will post the working python code followed by my attempt to do the same in Qt.
Working Python code
request = urllib2.Request(My_Url, data=body) request.add_header('Content-Type', 'text/plain') base64string = base64.encodestring('%s:%s' % (username,password)).replace('\n','') request.add_header("Authorization", "Basic %s" % base64string) request.get_method = lambda: 'PUT' urllib2.urlopen(request)
Attempt in Qt
QNetworkAccessManager manager; QByteArray PIStr = "Some data"; QNetworkRequest request(QUrl(My_Url)); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain")); QString concatenated = username + ":" + password; QByteArray basicAuth = concatenated.toLocal8Bit().toBase64(); QString headerData = "Basic " + basicAuth; request.setRawHeader("Authorization",headerData.toLocal8Bit()); QNetworkReply* reply = manager.put(request,PIStr);
When I run the above Qt code I don't see any indication from the RESTful endpoint that data is being received. Is the python code doing something different from what I wrote in Qt that I'm missing? This is my very first experience developing a mobile app so I could be missing some sort of setup step like enabling the app to access the phone's network resources for example.
Hope I stated the problem clearly and thanks for any help possible,
Hi and welcome to devnet,
If your attempt in Qt code is put in a function, your manager variable probably gets out of scope and destroyed before the request has been sent.
On a side note, there's no need for harderData to be a QString. Make it a QByteArray and avoid an unnecessary conversion. Same goes for concatenated.
Thank you for the quick reply. Yes the Qt code is being called in a function so the manager variable likely was going out of scope. I changed the QString variables to QByteArray as you suggested and added a QEventLoop to make sure the request is fully sent, but I'm still not seeing anything come through on the RESTful endpoint. Here is my updated code:
QNetworkAccessManager manager; QByteArray PIStr = "Some data"; QNetworkRequest request(QUrl(My_Url)); request.setHeader(QNetworkRequest::ContentTypeHeader, QString("text/plain")); QByteArray concatenated = username + ":" + password; QByteArray basicAuth = concatenated.toBase64(); QByteArray headerData = "Basic " + basicAuth; request.setRawHeader("Authorization",headerData); QNetworkReply* reply = manager.put(request,PIStr); QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec();
Will this event loop correctly wait until the put request has completed?
Thanks again for the help.
Silly question but: did you check that your My_Url content is valid ?
It definitely wasn't a silly question because it got me thinking about the fact that the IP address of my desktop is part of the URL, which led me to try a ping from my phone to the desktop. The ping was unsuccessful and I figured out it was due to the firewall running on my desktop. After disabling it, the ping now works but my Qt app still isn't successfully sending data to the REST endpoint.
I've confirmed the actual content of My_Url is valid because my python system does a put request to the same URL and doesn't have this problem.
You should also connect the error signal to see if you it tells you something useful.