qt restapi post no response - qt

I transfer data with "qt" over rest api on an nestJs service. the nestJs service work fine, but I don't receive any response in "qt".
here a snippet from qt:
QNetworkRequest request;
request.setUrl(myUrl);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkAccessManager *restClient;
restClient = new QNetworkAccessManager();
QNetworkReply *replay = restClient->post(request, *payload);
QByteArray result = replay->readAll();
qDebug() << result;
the console print is always:
""
the correct response from my nestJs service is (received with insomnia rest client tool):
{
"Generated": {},
"ErrorCode": 200,
"ErrorText": "OK"
}
thanks for help.

Requests are asynchronous so you must use the finished signal:
QNetworkReply *replay = restClient->post(request, *payload);
QObject::connect(replay, &QNetworkReply::finished, [replay](){
QByteArray result = replay->readAll();
qDebug() << result;
replay->deleteLater();
});

Related

Does QNetworkAccessManager support HTTPS proxy?

I compiled OpenSSL on my Windows machine and was able to do HTTPS queries with QNetworkAccessManager, but when I try to add HTTPS proxy
QNetworkAccessManager m_nm;
connect(&m_nm, &QNetworkAccessManager::proxyAuthenticationRequired, this, &BinanceReceiver::onProxyAuthenticationRequired);
connect(&m_nm, &QNetworkAccessManager::sslErrors, this, &BinanceReceiver::onSslErrors);
QNetworkProxy m_proxy(QNetworkProxy::HttpProxy, "host.com", 3129, "user", "password");
m_nm.setProxy(m_proxy);
QNetworkRequest request;
request.setUrl(MakeUrl(url));
QNetworkReply* reply = m_nm.get(request);
QObject::connect(reply, &QNetworkReply::finished, [this, reply]()
{
if (reply->error())
{
netLogger.error(reply->errorString());
}
else
{
//...
}
//Ensure it is deleted after this handler is called, but not before.
delete reply;
});
it stops working, I do not get the reply at all and neither proxyAuthenticationRequired nore sslErrors is triggered.
It is a Squid HTTPS proxy with the authentication.
Does QNetworkAccessManager support HTTPS proxy?

Twitter api error "code 32 Could not authenticate you" when trying to upload images

I am trying to upload photos to twitter from my app and i am using https://github.com/pipacs/o2 library for OAuth.
The following is the code that i am using:
QFile file(imgPath);
if (!file.open(QIODevice::ReadOnly))
{
return false;
}
QByteArray m_buffer = file.readAll();
O1Requestor* requestor = new O1Requestor(d->netMngr, d->o1Twitter, this);
QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
reqParams << O0RequestParameter(QByteArray("media"), m_buffer);
reqParams << O0RequestParameter(QByteArray("media_type"), QByteArray("image/jpeg"));
QByteArray postData = O1::createQueryParameters(reqParams);
QUrl url = QUrl("https://upload.twitter.com/1.1/media/upload.json");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
QNetworkReply *reply = requestor->post(request, reqParams, postData);
The result is the following:
ERROR: "Host requires authentication"
Content: "{"errors":[{"code":32,"message":"Could not authenticate you."}]}"
I tried doing something simple like posting a tweet saying Hello to test the authentication using statuses/update endpoint and it worked with no errors.
The following is the code also if it is required:
QUrl url2 = QUrl("https://api.twitter.com/1.1/statuses/update.json);
reqParams = QList<O0RequestParameter>();
reqParams << O0RequestParameter(QByteArray("status"), "Hello");
postData = O1::createQueryParameters(reqParams);
request.setUrl(url2);
request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
QNetworkReply *reply = requestor->post(request, reqParams, postData);
Could you please help me with this issue.
Thanks
Similar to this answer, you will need to ensure that the image content in m_buffer is sent as a base-64 encoded string. Otherwise, the Twitter API will return error 32.

Google assistant gRPC call hung

Server doesn't reply when a GRPC call is made to "embeddedassistant.googleapis.com". I see the request being received at google server end when I check the Google API web interface.
I set the request with proper configuration (when I set wrong configuration I do get error message from server). Is there anything I'm missing here?
std::string Converse(const std::string& user) {
AudioInConfig audio_in_config;
audio_in_config.set_encoding(google::assistant::embedded::v1alpha1::AudioInConfig_Encoding_FLAC);
audio_in_config.set_sample_rate_hertz(16000);
AudioOutConfig audio_out_config;
audio_out_config.set_encoding(google::assistant::embedded::v1alpha1::AudioOutConfig_Encoding_MP3);
audio_out_config.set_sample_rate_hertz(16000);
audio_out_config.set_volume_percentage(50);
ConverseState converse_state;
const char * conversation_state = "a";
converse_state.set_conversation_state(conversation_state);
ConverseConfig config;
config.set_allocated_audio_in_config(&audio_in_config);
config.set_allocated_audio_out_config(&audio_out_config);
config.set_allocated_converse_state(&converse_state);
ConverseRequest request;
request.set_allocated_config(&config);
ConverseResponse reply;
ClientContext context;
auto status = stub_->Converse(&context, request, &reply);
config.release_audio_in_config();
config.release_audio_out_config();
config.release_converse_state();
request.release_config();
// Act upon its status.
if (status.ok()) {
return reply.result().conversation_state();
} else {
std::cout << "Error: " << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
return "";
}
Why have you set the conversation_state to "a". It should be in bytes or empty. You also need to send an audio data captured depending upon the situation. You can do that by including the ALSA sound API in C++ in your code.
The conversation_state value returned in the prior ConverseResponse. Omit (do not set the field) if there was no prior ConverseResponse. If there was a prior ConverseResponse, do not omit this field; doing so will end that conversation (and this new request will start a new conversation).
You can see from here:-
https://developers.google.com/assistant/sdk/reference/rpc/google.assistant.embedded.v1alpha1

Get http code request

U use QNetworkRequest to send post request. How can I get HTTP code of request? I send some request to server, on server I can see my request, but i have to check http code which server will return to application.
QNetworkRequest can not be used without QNetworkAccessManager that's responsible for making the actual request to the web server. Each request done by QNetworkAccessManager instance returns QNetworkReply where you should look for the status code from the server. It's located inside the QNetworkReply instance headers.
The request is asynchronous so it can be catch when signal is triggered.
Easiest example would be:
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
Then in the slot implementation:
void replyFinished(QNetworkReply *resp){
QVariant status_code = resp->attribute(QNetworkRequest::HttpStatusCodeAttribute);
status_code.is_valid(){
// Print or catch the status code
QString status = status_code.toString(); // or status_code.toInt();
qDebug() << status;
}
}
Have a look on the official documentation. It explains all in details.
QNetworkRequest
QNetworkAccessManager

QtWebkit: How to check HTTP status code?

I'm writing a thumbnail generator as per an example in the QtWebkit documentation. I would like to avoid screenshots of error pages such as 404 not found or 503 Internal server error.
However, the QWebPage::loadFinished() signal is always emitted with ok = true even when the page gives an HTTP error. Is there a way in QtWebkit to check the HTTP status code on a response?
Turns out you need to monitor the QNetworkAccessManager associated with your QWebPage and wait for a finished(...) signal. You can then inspect the HTTP response and check its status code by asking for the QNetworkRequest::HttpStatusCodeAttribute attribute.
It's better explained in code:
void MyClass::initWebPage()
{
myQWebPage = new QWebPage(this);
connect(
myQWebPage->networkAccessManager(), SIGNAL(finished(QNetworkReply *)),
this, SLOT(httpResponseFinished(QNetworkReply *))
);
}
void MyClass::httpResponseFinished(QNetworkReply * reply)
{
switch (reply->error())
{
case QNetworkReply::NoError:
// No error
return;
case QNetworkReply::ContentNotFoundError:
// 404 Not found
failedUrl = reply->request.url();
httpStatus = reply->attribute(
QNetworkRequest::HttpStatusCodeAttribute).toInt();
httpStatusMessage = reply->attribute(
QNetworkRequest::HttpReasonPhraseAttribute).toByteArray();
break;
}
}
There are more NetworkErrors to choose from, e.g. for TCP errors or HTTP 401.
This is what I'm using in a porting project. It checks the reply and decides to start backing off making request or not. The backing off part is in progress but I left the comments in.
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
Q_CHECK_PTR(reply);
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (!statusCode.isNull() && statusCode.toInt() >= 400){
//INVALID_SERVER_RESPONSE_BACKOFF;
qDebug() << "server returned invalid response." << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return;
}else if (!statusCode.isNull() && statusCode.toInt() != 200){
//INVALID_SERVER_RESPONSE_NOBACKOFF;
qDebug() << "server returned invalid response." << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return;
}

Resources