Bearer authentication with Qt (QNetworkAccessManager) - c++

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?

Related

QNetworkReply - Strange error in enum, OperationCanceled instead of Timeout?

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

QNetworkReply::NetworkError(ProtocolUnknownError)

In my project, I am attempting to download a YouTube profile picture. The YouTube API returns this link https://yt3.ggpht.com/-7ipuUvDjVT8/AAAAAAAAAAI/AAAAAAAAAAA/hSPOcUsb1nw/s240-c-k-no-mo-rj-c0xffffff/photo.jpg
However, using the same function for downloading files from my own website doesn't work with this URL. I get QNetworkReply::NetworkError(ProtocolUnknownError) in the application output.
Here is my code:
QByteArray downloadFileData(QString url)
{
QNetworkRequest request;
request.setUrl(QUrl(url));
QNetworkReply *reply = manager->get(request);
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
if(reply->error() == QNetworkReply::NoError)
{
return reply->readAll();
}
else
{
qDebug() << reply->error();
}
reply->deleteLater();
return "";
}
When I pass that url to this function, I get that error. What is going on?
Thanks for your time

QNetworkAccessManager does not emit signal

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();
}

Qt or libcurl c++: Facebook api POST request to image upload

Good day. I can't understend how create a POST request to upload an image. I was searching in the net, and found several versions. But is always response for me (after request) - "(# 324) Requires upload file".
Thank you!
ui->webView->load(QUrl("https://www.facebook.com/dialog/oauth?"
"client_id=XXXXXXXXXX&"
"display=popup&"
"response_type=token&"
"scope=user_status,user_photos,publish_actions&"
"redirect_uri=https://www.facebook.com/connect/login_success.html"));
1
QString uploadUrl = "https://graph.facebook.com/me/photos?access_token=" +
accessToken;
QString photoPath = QCoreApplication::applicationDirPath() + "/image_example.png";
QFileInfo fileInfo(photoPath);
QFile file(photoPath);
QString comment = "User provided message";
QString bound="---------------------------17673466415141";
QByteArray data;
data.append("--" + bound + "\r\n");
data.append("Content-Disposition: form-data; name=\"access_token\"\r\n\r\n");
data.append(accessToken + "\r\n");
data.append("--" + bound + "\r\n");
data.append("Content-Disposition: form-data; name=\"source\"; filename=\""
+ file.fileName()+"\"\r\n");
data.append("Content-Type: image/" + fileInfo.suffix().toLower() + "\r\n\r\n");
data.append(file.readAll());
data.append("\r\n");
data.append("--" + bound + "\r\n");
data.append("Content-Disposition: form-data; name=\"message\"\r\n\r\n");
data.append(comment);
data.append("--" + bound + "\r\n");
QNetworkRequest request(uploadUrl);
request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Language", "en-us,en;q=0.5");
request.setRawHeader("Accept-Encoding", "gzip,deflate");
request.setRawHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
request.setRawHeader("Keep-Alive", "300");
request.setRawHeader("Content-Type",
QString("multipart/form-data; boundary=" + bound).toLatin1());
request.setRawHeader("Content-Length", QString(data.size()).toLatin1());
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
QNetworkReply * reply = manager->post(request, data);
QEventLoop wait;
connect(manager, SIGNAL(finished(QNetworkReply*)), &wait, SLOT(quit()));
connect(manager, SIGNAL(finished(QNetworkReply*)), manager, SLOT(deleteLater()));
QTimer::singleShot(10000, &wait, SLOT(quit()));
wait.exec();
QByteArray answer = reply->readAll();
reply->deleteLater();
qDebug() << answer;
2
QString uploadUrl = "https://graph.facebook.com/me/photos?access_token=" +
accessToken;
QString photoPath = QCoreApplication::applicationDirPath() + "/image_example.png";
QFileInfo fileInfo(photoPath);
QFile file(photoPath);
QPixmap pixmap;
pixmap.load(photoPath);
QByteArray data;
QBuffer buffer(&data);
buffer.open(QIODevice::ReadWrite);
pixmap.save(&buffer, "png");
buffer.close();
QHttpMultiPart * multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"source\"; filename=\""+ file.fileName()));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"message\""));
imagePart.setBody(data);
multiPart->append(imagePart);
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
QNetworkReply * reply = manager->post(request, multiPart);
QEventLoop wait;
connect(manager, SIGNAL(finished(QNetworkReply*)), &wait, SLOT(quit()));
connect(manager, SIGNAL(finished(QNetworkReply*)), manager, SLOT(deleteLater()));
QTimer::singleShot(10000, &wait, SLOT(quit()));
wait.exec();
QByteArray answer = reply->readAll();
reply->deleteLater();
qDebug() << answer;
I am actually using something similar to your second example. But you need to:
1/ set the size of your image in the imagePart header
2/ you are re-defining ContentDisposition. You need only the first one.
So to recap:
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(type.name()));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"source\"; filename=\""+ file.fileName()));
imagePart.setHeader(QNetworkRequest::ContentLengthHeader, QString::number(fileInfo.size()).toLocal8Bit());
imagePart.setBody(file.readAll());
multiPart->append(imagePart);

create a http communication on blackberry 10 cascade

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);