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);
// ...
Related
I want to extract informations from youtube using Qt (QNetworkAccessManager). While the code below works with other websides, i dont get any data from youtube. Any idea what the configuration of QNetworkRequest should be?
PS. Yes i know i can achieve it by using YoutubeApi.
Youtube::Youtube(QObject *parent) : QObject(parent)
{
manager = new QNetworkAccessManager(this);
QObject::connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(readyRead(QNetworkReply*)));
}
void Youtube::makeRequest()
{
qDebug() << "YOUTUBE::makeRequest()";
request.setUrl(QUrl("www.youtube.com/"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
manager->get(request);
}
void Youtube::readyRead(QNetworkReply *replay)
{
qDebug() << replay->readAll();
QByteArray dataTemp = replay->readAll();
website = dataTemp.toStdString();
}
You can try this to get info about a video and store in a QJsonDocument object:
QNetworkAccessManager* net = new QNetworkAccessManager(this);
net->get(QNetworkRequest(QUrl("https://noembed.com/embed?
url=https://www.youtube.com/watch?v=dQw4w9WgXcQ")));
connect(net, &QNetworkAccessManager::finished,[](QNetworkReply* reply)
{
QString output = reply->readAll();
QJsonDocument doc;
QJsonParseError errorPtr;
doc = QJsonDocument::fromJson(output.toUtf8(), &errorPtr);
if(! doc.isNull())
{
QJsonObject videoInfoJson = doc.object();
qDebug() <<videoInfoJson.value("title").toString();
}
});
I am using qnetworkaccessmanager to login to a website, i am setting user and password in rowHeader but getting empty response in code, but the same request with user and password set in header works properly using Postman tool, can anyone suggest what could be the issue ?
QString user = "user";
QString pass = "testPassword";
QByteArray data1 = user.toLocal8Bit().toBase64();
QByteArray data2 = pass.toLocal8Bit().toBase64();
QNetworkRequest request = QNetworkRequest(QUrl("http://server_address/b1/login"));
request.setRawHeader("user", data1);
request.setRawHeader("password", data2);
QNetworkReply *reply = manager->get(request);
and i am fetching reply using below code -
manager = new QNetworkAccessManager();
QObject::connect(manager, &QNetworkAccessManager::finished,
this, [=](QNetworkReply *reply) {
if (reply->error()) {
qDebug() << reply->errorString();
return;
}
QString answer = QString::fromUtf8(reply->readAll());
qDebug() << answer;
bool isFinished = reply->isFinished();
bool isRunning = reply->isRunning();
QNetworkReply::NetworkError err = reply->error();
QByteArray bts = reply->readAll();
QString str(bts);
qDebug() << str;
Below is the postman screenshot with headers
QString user = "testUser"; // Use same "user" value as you used in your Postman example
QString pass = "testPassword";
QByteArray data1 = user.toLocal8Bit(); // Remove toBase64()
QByteArray data2 = pass.toLocal8Bit(); // Remove toBase64()
QNetworkRequest request = QNetworkRequest(QUrl("http://server_address/b1/login"));
request.setRawHeader("user", data1);
request.setRawHeader("password", data2);
QNetworkReply *reply = manager->get(request);
I have an existing C++/Qt source code for the firmware update. HTTP client used to download the file.
This piece of code works fine if I'll provide http://<path to file>
But http client failed to download from ftp://<path to down load>. It shows downloaded file size zero with ftp.
As per StackOverflow, It should work for for both. I try to use setScheme("ftp") and other small changes. But does not work.
void HttpClient::onDownloadProgress(qint64 bytesReceived,
qint64 bytesTotal)
{
emit downloadUpdateProgress(
static_cast<int>((bytesReceived * 1.0f / bytesTotal * 1.0f) * 100));
}
void HttpClient::onReadyRead()
{
auto reply = qobject_cast<QNetworkReply *>(QObject::sender());
if (reply) {
QNetworkRequest request(reply->request());
auto device = qobject_cast<QIODevice *>(request.originatingObject());
if (device) {
device->write(reply->readAll());
}
}
}
bool HttpClient::post(const QUrl &url, const QByteArray &data,
QIODevice *device)
{
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::AlwaysNetwork);
request.setSslConfiguration(getSslConfig());
request.setOriginatingObject(device);
QNetworkReply *reply = _networkAccessManager->post(request, data);
connect(reply, &QNetworkReply::readyRead, this, &HttpClientImpl::onReadyRead);
bool result = waitForFinished(reply, 30 * 1000);
return result;
}
bool HttpClientImpl::get(const QUrl &url, QIODevice *device)
{
QNetworkRequest request(url);
request.setSslConfiguration(getSslConfig());
request.setOriginatingObject(device);
QNetworkReply *reply = _networkAccessManager->get(request);
connect(reply, &QNetworkReply::downloadProgress, this,
&HttpClientImpl::onDownloadProgress);
connect(reply, &QNetworkReply::readyRead, this, &HttpClientImpl::onReadyRead);
bool result = waitForFinished(reply);
return result;
}
It should download the correct file size.
I am doing a simple HTTP get request to www.google.co.in but I am getting empty string in response.
Here is my code:
void MainWindow::on_pushButton_clicked()
{
QNetworkAccessManager * mgr = new QNetworkAccessManager(this);
connect(mgr,SIGNAL(finished(QNetworkReply*)),this,SLOT(onfinish(QNetworkReply*)));
QUrl url("www.google.co.in");
url.setScheme("http");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
mgr->get(QNetworkRequest(QUrl("www.google.co.in")));
}
void MainWindow::onfinish(QNetworkReply *rep)
{
QByteArray bts = rep->readAll();
QString str(bts);
qDebug() << str;
}
Output is :""
Facing same issue when doing post request to my own server.
In pro file I have done QT += core gui network
You have to add the correct URL, in addition it is recommended that you use the new connection between signals and slots, and finally you must remove the QNetworkReply:
void MainWindow::on_pushButton_clicked()
{
QUrl url("https://www.google.co.in/");
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
connect(mgr,&QNetworkAccessManager::finished,this,&MainWindow::onfinish);
mgr->get(QNetworkRequest(url));
}
void MainWindow::onfinish(QNetworkReply *rep)
{
QByteArray bts = rep->readAll();
QString str(bts);
qDebug() << str;
rep->deleteLater();
}
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);