I was trying to perform Bearer authentication for https://developer.olx.ua/api/doc#tag/Adverts/paths/~1adverts/get from my Qt app. I use QNetworkAccessManager. But I couldn't find any help on this.
I try this code
QNetworkAccessManager *manager = new QNetworkAccessManager;
QEventLoop loop;
QObject::connect(manager, &QNetworkAccessManager::finished, &loop,
&QEventLoop::quit);
const QUrl url("https://www.olx.ua/api/partner/threads");
QNetworkRequest request {url};
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QString temp = "Bearer " + marketplaceAccessToken;
request.setRawHeader("Authorization", temp.toLocal8Bit());
request.setRawHeader("Version", "2.0");
QNetworkReply *reply = manager->get(request);
loop.exec();
QByteArray dataReply = reply->readAll();
qDebug() << dataReply;
The server reply is {"error":{"status":400,"title":"Bad Request","detail":"Invalid owner in token"}}
How can I fix it?
My API server is turned off and i run following code.
I dont understand why QNetworkReply::OperationCanceledError error enum is returned instead of QNetworkReply::TimeoutError. What is wrong? Am i doing something wrong or is it Qt bug?
From documentation that error should be if "the operation was canceled via calls to abort() or close() before it was finished."
I see no reason for that.
QByteArray encodedData = data.toUtf8();
QUrl url("http://myapi/jsonrpc");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkAccessManager manager;
manager.setTransferTimeout(500);
QNetworkReply* reply = manager.post(request, encodedData);
QEventLoop loop;
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
if (reply->error() != QNetworkReply::NoError) {
QString errorMsg = QString("HTTP Network request has failed. Code: ") + QVariant::fromValue(reply->error()).toString();
delete reply;
// error
// here i got QNetworkReply::OperationCanceledError
}
QByteArray response = reply->readAll();
//ok
I want to upload a PNG image with the Imgur API. When I converted a test image (png) to Base64, I got an error that it was not a valid file type. Then I took the test image from the Imgur API documentation (R0lGODlhAQABAIAAAAAAAP//yH5BAEAAAAALAAAABAAEAAAIBRAA7), which worked for an upload, converted it to a "real" image via a converter and tested a Base64 conversion with it. However, I get a different Base64 string (R0lGODlhAQABAOKCrAAAAAAAw7/Dv8O/IcO5BAEAAAAALAAAAAABAAEAAAIBRAA7).
Code snippet:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QUrl url("https://api.imgur.com/3/image");
QNetworkRequest request(url);
request.setRawHeader("Authorization", "Client-ID <hereIsTheClientID>");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QFile image ("C:/Users/pietr/Desktop/image.gif"); // Result from converting example Base64 from Imgur API-Docs - this file can be read by photo viewers
image.open(QIODevice::ReadOnly);
QTextStream in (&image);
QByteArray imageArray = in.readAll().toUtf8().toBase64();
qDebug() << "Image data:" << imageArray;
QUrlQuery params;
params.addQueryItem("image", imageArray);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
manager->post(request, params.query().toUtf8());
But the reply is...
{
"data":
{
"error":
{
"code":1003,
"message":"File type invalid (2)",
"type":"ImgurException",
"exception":[]},"request":"\/3\/image",
"method":"POST"
},
"success":false,
"status":400
}
Am I making a mistake with the Base64 convert? Why do I get a different value out of the same images?
The image is not sent in the query but as form-data. Using an old answer and applied in your case the solution is:
#include <QCoreApplication>
#include <QFile>
#include <QHttpMultiPart>
#include <QNetworkAccessManager>
#include <QNetworkReply>
QHttpMultiPart *buildMultpart(const QVariantMap & data, const QMap<QString, QString> filenames){
QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QVariantMap::const_iterator i_data = data.constBegin();
while (i_data != data.constEnd()) {
QHttpPart postpart;
postpart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(i_data.key()));
postpart.setBody(i_data.value().toByteArray());
multipart->append(postpart);
++i_data;
}
QMap<QString, QString>::const_iterator i_filenames = filenames.constBegin();
while (i_filenames != filenames.constEnd()) {
QFile *file = new QFile(i_filenames.value());
if(!file->open(QIODevice::ReadOnly)){
delete file;
continue;
}
QHttpPart postpart;
postpart.setHeader(QNetworkRequest::ContentDispositionHeader,
QString("form-data; name=\"%1\"; filename=\"%2\"")
.arg(i_filenames.key(), file->fileName()));
postpart.setBodyDevice(file);
multipart->append(postpart);
file->setParent(multipart);
++i_filenames;
}
return multipart;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const QString CLIENT_ID = QLatin1String("{{clientId}}");
const QString API_URL = QLatin1String("https://api.imgur.com");
QNetworkAccessManager manager;
QNetworkRequest request;
QUrl url(API_URL);
url.setPath("/3/upload");
request.setUrl(url);
request.setRawHeader("Authorization", ("Client-ID "+ CLIENT_ID).toUtf8());
QMap<QString, QString> filenames;
filenames["image"] = "C:/Users/pietr/Desktop/image.gif";
QHttpMultiPart *multipart = buildMultpart({}, filenames);
QNetworkReply *reply = manager.post(request, multipart);
multipart->setParent(reply);
QObject::connect(reply, &QNetworkReply::finished, [reply](){
if(reply->error() == QNetworkReply::NoError){
qDebug().noquote() << reply->readAll();
}
else{
qDebug() << reply->error() << reply->errorString();
}
reply->deleteLater();
QCoreApplication::quit();
});
return a.exec();
}
Output:
{"status":200,"success":true,"data":{"id":"iT63Heu","deletehash":"JRIdjdWP7lMhzuG","account_id":null,"account_url":null,"ad_type":null,"ad_url":null,"title":null,"description":null,"name":"","type":"image/gif","width":100,"height":75,"size":6166,"views":0,"section":null,"vote":null,"bandwidth":0,"animated":false,"favorite":false,"in_gallery":false,"in_most_viral":false,"has_sound":false,"is_ad":false,"nsfw":null,"link":"https://i.imgur.com/iT63Heu.gif","tags":[],"datetime":1634600948,"mp4":"","hls":""}}
If you want to use base64 then change to:
// ...
request.setRawHeader("Authorization", ("Client-ID "+ CLIENT_ID).toUtf8());
QVariantMap data;
QFile image("C:/Users/pietr/Desktop/image.gif");
if(image.open(QIODevice::ReadOnly)){
data["image"] = image.readAll().toBase64();
data["type"] = "base64";
image.close();
}
QHttpMultiPart *multipart = buildMultpart(data, {});
QNetworkReply *reply = manager.post(request, multipart);
// ...
So I have this code:
QUrl url("http://...");
QNetworkRequest request(url);
QNetworkReply *reply = m_networkManager->get(request);
connect(reply, SIGNAL(finished()), SLOT(onRequestCompleted()));
connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),SLOT(onError(QNetworkReply::NetworkError)));
and I cant get signal to the other fuction
void IpResolver::onRequestCompleted()
{
QString webContent;
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
if (reply)
{
if (reply->error() == QNetworkReply::NoError)
{
QString webContent = reply->readAll();
}
}
}
I cant figure out the solution, help please.
I don't know what exactly you want, but:
Why do you use reply pointer instead of some kind onRequestCompleted(QNetworkReply *reply)?
If you do so:
QUrl url("http://...");
QNetworkRequest request(url);
connect(m_networkManager, &QNetworkAccessManager::finished, this, &IpResolver::onRequestCompleted);
m_networkManager->get(request);
And your slot will be, for example:
void IpResolver::onRequestCompleted(QNetworkReply *reply)
{
QString webContent;
if (reply->error() == QNetworkReply::NoError)
webContent = reply->readAll();
}
I'm newbie on development blackberry 10 cascades. I need to use httpget to connect on file xml and get dat from it to display it on list.
There is an example can help me to make http communication or a tutoriel?
All the links for http communication like this https://developer.blackberry.com/cascades/documentation/device_platform/networking/tutorial_http_comm.html didn't work I get 404
Use QNetworkAccessManager, QNetworkRequest and QNetworkReply classes to make http connection.
QNetworkAccessManager* netManager = new QNetworkAccessManager();
QUrl myurl(yourURL);
QNetworkRequest req(url);
QNetworkReply* ipReply = netManager->get(req);
connect(ipReply, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReply(QNetworkReply*)));
}
In onReply slot parse your response
if (reply) {
if (reply->error() == QNetworkReply::NoError) {
int available = reply->bytesAvailable();
if (available > 0) {
int bufSize = sizeof(char) * available + sizeof(char);
QByteArray buffer(bufSize, 0);
int read = reply->read(buffer.data(), available);
response = QString(buffer);
}
} else {
response =
QString("Error: ") + reply->errorString()
+ QString(" status:")
+ reply->attribute(
QNetworkRequest::HttpStatusCodeAttribute).toString();
}
reply->deleteLater();
}
Visit this page for more information
use this code...
QNetworkAccessManager* netManager = new QNetworkAccessManager();
QUrl myurl("http://******");
QNetworkRequest req(myurl);
QNetworkReply* ipReply = netManager->get(req);
QEventLoop eventLoop;
QObject::connect(ipReply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
std::cout << "finished" << std::endl; //request finished here
requestFinished(ipReply);