QNetworkReply::RemoteHostClosedError - qt

I was learning the Github API and wanted to create an Issue on github by Qt.
But, when I submit my Issue, the "Debug Console" said
QNetworkReply::RemoteHostClosedError
(I catched error).
I don't know why, please help me!
Code on Github:
void MainWindow::on_pushButton_2_clicked()
{
QString id = ui->ID_Send->text();
QJsonObject JJ;
QJsonDocument jd;
JJ["title"] = ui->Title->text();
JJ["body"] = ui->Comment->toPlainText();
QHttpMultiPart *part = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart info;
info.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/json"));
jd.setObject(JJ);
info.setBody(jd.toJson());
part->append(info);
QNetworkRequest request;
qDebug()<<"https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret;
request.setUrl(QUrl("https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret));
QNetworkReply* reply = manager->post(request,part);
QObject::connect(reply, &QNetworkReply::finished, [reply, this] () {
if (reply->error() == QNetworkReply::NoError) {
ui->status->setText("ok");
} else {
ui->status->setText("failed");
qDebug()<<reply->error();
}
reply->deleteLater();
});
}

You can take example in this answer or here.
Compared to your code, it sets the header to "application/json".
And it uses a QNetworkAccessManager to send network requests and receive replies.
QUrl url("https://api.github.com/repos/" + owner +"/" + project + "/tags");
qInfo() << url.toString();
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkAccessManager nam;
QNetworkReply * reply = nam.get(request);

Related

Error transferring https://speech.googleapis.com/v1/speech:recognize?key=,myKey> - server replied: Bad Request [Problem on Windows OS]

I am using google speech-to-text api to convert my audio file to text. Following is my code(in Qt):
`QString fileName = QDir::currentPath() + "/audio.wav"; //this is my audio file
QFile audioFile(fileName);
if(!audioFile.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::critical(0,"Error",fileName+" Not found!");
ui->pushButton_4->setText("Speech to text");
return;
}
int idx = ui->comboBox->currentIndex();
QString enc;
if (idx == -1)
enc = "en-US";
else
enc = ui->comboBox->itemData(idx).toString(); //Language selected by user
QByteArray audioData=audioFile.readAll();
QUrl url("https://speech.googleapis.com/v1/speech:recognize");
QUrlQuery query;
query.addQueryItem("key","myKeyHere...");
url.setQuery(query);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,"audio/x-flac");
QJsonObject json;
QJsonObject config;
config["encoding"]="FLAC";
config["sampleRateHertz"]=44100;
config["languageCode"]=enc;
json["config"]=config;
QJsonObject audio;
audio["content"]=QString::fromLatin1(audioData.toBase64());
json["audio"]=audio;
QByteArray jsonData=QJsonDocument(json).toJson();
QNetworkAccessManager *manager=new QNetworkAccessManager();
QNetworkReply *reply=manager->post(request,jsonData);
QObject::connect(reply,&QNetworkReply::finished,[this,reply](){
if(reply->error()!=QNetworkReply::NoError){
QMessageBox::critical(0,"Error Occured",reply->errorString());
qDebug() << reply->readAll();
ui->pushButton_4->setText("Speech to text");
return;
}
else if(reply->error()==QNetworkReply::UnknownNetworkError){
QMessageBox::warning(0,"Network Error","Please check your internet connection and try again!");
ui->pushButton_4->setText("Speech to text");
}
else if(reply->isFinished() && reply->error()==QNetworkReply::NoError){
QJsonDocument responseJson=QJsonDocument::fromJson(reply->readAll());
QJsonObject object=responseJson.object();
QString ResponseText=object["results"].toArray()[0].toObject()
["alternatives"].toArray()[0].toObject()["transcript"].toString();
QTextCursor cur = curr_browser->textCursor();
qDebug() << "Response Data :" << ResponseText;
cur.insertText(ResponseText);
ui->pushButton_4->setText("Speech to text");
}
reply->deleteLater();
});`
This code is working perfectly on Ubuntu but not on windows. When i run this on Ubunutu, i am receiving the response, but on windows i receive the following error:
Error transferring https://speech.googleapis.com/v1/speech:recognize?key=,myKey> - server replied: Bad Request
Following is the code to record an audio file:
`if (m_audioRecorder->state() == QMediaRecorder::StoppedState) {
QString fileName = QDir::currentPath() + "/audio.wav";
m_audioRecorder->setOutputLocation(QUrl::fromLocalFile(fileName));
qDebug()<<"Recording your audio!!";
ui->pushButton_4->setText("Stop ?");
QAudioEncoderSettings settings;
settings.setCodec("audio/x-flac");
settings.setSampleRate(0);
settings.setBitRate(0);
settings.setChannelCount(1);
settings.setQuality(QMultimedia::EncodingQuality(2));
settings.setEncodingMode(QMultimedia::ConstantQualityEncoding);
m_audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), "");
m_audioRecorder->record();
}
else {
qDebug()<<"stopped your recording!";
ui->pushButton_4->setText("Processing ...");
m_audioRecorder->stop();
speechToTextCall(); //calling the code to send request to google api
}`
Can anyone help please?
I tried changing the encodig and container type, but nothing worked on Windows.
I have found the solution of above problem. Windows does not recognize the auido/x-flac encoding so i modified my encoding code as follows:
'
#ifdef Q_OS_WIN
settings.setCodec("audio/pcm");
#else
settings.setCodec("audio/x-flac");
#endif
'
I made the same changes at other two places where encoding was set and it worked on windows as well.

NetworkReply HttpStatusCode QVariant(Invalid)

I'm using the code below to make a http request:
QNetworkReply* ApiRequest::req(QString url, QString method, QByteArray data) {
QByteArray request_method = method.toUtf8();
QNetworkAccessManager* manager = new QNetworkAccessManager();
QNetworkRequest request("http://127.0.0.1:9090" + url);
request.setRawHeader("Content-Type", "application/json");
QNetworkReply* reply = manager->sendCustomRequest(request, request_method, data);
return reply;
}
void ApiRequest::requestConfig()
{
NetworkReply* reply = req("/configs",
"GET",
"");
}
The Remote server did execute the request and reply a 204 code.
I have used wireshark to capture and make sure it had reply a 204 No Content.
However, the output there is QVariant(Invalid), the toInt output is 0.
I tried to change PUT to GET but it still not working.
You are analyzing the state even when the request has not been made so it is valid that the result is null, what you should do is analyze it when the finished signal is emitted:
QNetworkReply* reply = mg->sendCustomRequest(request, "PUT", "....some json....");
connec(reply, &QNetworkReply::finished, [reply](){
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
});
Update:
connec(mg, &QNetworkAccessManager::finished, [](QNetworkReply *reply){
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
});
Update 2:
Is there a way to return that reply when it is finished?
Yes, use a QEventLoop, but in general it is a bad design since you should use signals and slots to notify you of the changes.
QNetworkReply* ApiRequest::req(const QString & url, const QString & method, const QByteArray & data) {
QByteArray request_method = method.toUtf8();
QNetworkAccessManager manager;
QNetworkRequest request("http://127.0.0.1:9090" + url);
request.setRawHeader("Content-Type", "application/json");
QNetworkReply* reply = manager.sendCustomRequest(request, request_method, data);
QEventLoop loop;
connec(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
return reply;
}
// ...
void ApiRequest::requestConfig()
{
QNetworkReply* reply = req("/configs", "GET", "");
// ...
reply->deleteLater();
}
You can include QtNetworkReply and QEventLoop classes and use signal/slot mechanism.
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QUrl resource(url);
QNetworkRequest request(resource);
QNetworkReply *reply = manager->get(request);
QEventLoop loop;
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
QJsonObject jsonObject = QJsonDocument::fromJson(reply->readAll()).object();

QNetworkAccessManager: how to make sure download is finished?

If I do:
QNetworkRequest newRequest(url);
newRequest.setUrl(url);
QNetworkReply *reply = networkManager->get(newRequest);
connect(reply, SIGNAL(finished()), this, SLOT(onRetrievedDownLoadInfo()));
and
void myClass::onRetrievedDownLoadInfo()
{
QNetworkReply *reply = qobject_cast<QNetworkReply*>(QObject::sender());
if (!reply)
{
ui->upgradeLog->appendPlainText("Download failed, invalid context");
return;
}
//Remeber to delete the reply
//---------------------------
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{
ui->upgradeLog->appendPlainText("Download failed, invalid context");
return;
}
reply->readAll();
...
}
Can I say that when the program reaches line
reply->readAll();
All the content replied by the server is successfully received?
Is it possible the reply->readAll(); only returns part of the reply due to network failure?
The error is here:
connect(reply, SIGNAL(finished()), this, SLOT(onRetrievedDownLoadInfo()));
you are not doing it in the correct way. Use a QNetworkAccessManager to check the network is working:
QNetworkConfigurationManager manager;
req.setConfiguration(manager.defaultConfiguration());
connect(&req, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)));

QNetworkAccessManager returning empty results

I am struggling with qnetworkaccessmanager for quite sometime. I googled a lot, but I donot find a solution for this.
I am creating a client using qaccessmanager to talk with a rest server. QNetworkReply is not returning any results. The server is working properly but the client is not returning results. On top of that the server gets called 3 times and sometimes the server is crashing. Hope some one can figure out what is going wrong. I am attaching the client code.
I tried different approches like connecting finished signal of networkaccessmanager, qnetworkreply e.t.c. But all of them ends up in giving the same error "Connection Closed" or the readAll bytearray being empty.
void RestClientCore::ConnectToServer()
{
m_NetworkManager = new QNetworkAccessManager(this);
QUrl url("http://localhost");
url.setPort(5432);
QByteArray postData;
postData.append("/?userid=user");
postData.append("&site=site");
QNetworkReply *reply = m_NetworkManager->post(request,postData);
connect(reply, SIGNAL(readyRead()),this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(finished()), this, SLOT(onRequestCompleted()));
}
void RestClientCore::onRequestCompleted() {
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
if(reply->error())
{
qDebug() <<reply->bytesAvailable() << reply->errorString();
}
else
{
qDebug() << reply->readAll();
}
reply->deleteLater();
}
void RestClientCore::slotReadyRead()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
qDebug() << reply->readAll();
}
Thanks in advance
Regards
Rejo

QNetworkRequest to download an image?

I have used QNetworkRequest to retrieve xml off the web without problems:
request.setUrl(QUrl("http://api.somesite.com/api/4we35r/somefile.xml"));
myNetworkAccessManager->get(request);
How would I go about downloading an image? Ex:
http://www.mysite.com/27eye28/images/myimage.png
Do I just replace the xml url above with the png url? Do I have to do anything special?
Yes, replacing the URL is all that you have to do.
Here's a working example,
void MainWindow::GetImage(QString url)
{
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
QUrl url = QUrl(url);
QNetworkRequest request(url);
manager->get(request);
}
void MainWindow::replyFinished(QNetworkReply *reply)
{
if(reply->error() != QNetworkReply::NoError)
{
ui->textBrowser->setText("Error: " + reply->errorString());
}
else
{
QByteArray responseData = reply->readAll();
QFile file("d:\\myImage.png");
file.open(QIODevice::WriteOnly);
file.write((responseData));
file.close();
}
}

Resources