Get http code request - qt

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

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?

qt restapi post no response

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

ESP32: HttpClient.get() fails with -1

I'm programming my ESP32 with the ArduinoIDE and have a problem with HTTP GET. What I'm doing:
the ESP32 connects as WiFi client to an existing WiFi network using a static, fixed IP
a webserver is started which provides a webpage for OTA firmware update -> this works, the webpage is accessible via the static IP
using HttpClient I try to GET an other, remote webserver, but this fails
This is the code I'm using for the HTTP GET call:
static WiFiClient wifi;
HttpClient wlanHttp=HttpClient(wifi,"my.server.tld");
wlanHttp.get("/setpos.php?id=DEADBEEF"); // -> this fails with error code -1
wlanHttp.responseStatusCode(); // follow-up error -1
wlanHttp.stop();
Any idea what goes wrong here?
The confusing part here is the ESP32 has a built in http client called HTTPClient. The one for Arduino is called HttpClient and I'd like to find the guy who decided on that name and see if he's okay. HTTPClient has a routine called getString() that is a lovely way to gather info from a json api call, but HttpClient won't compile with that because it has no clue what that is.
On ESp32 (if using the HTTPClient.h) the code should look like that:
static WiFiClient wifi;
HttpClient wlanHttp;
wlanHttp.begin("http://my.server.tld/setpos.php?id=DEADBEEF"); //Specify the URL
int httpCode = wlanHttp.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
if (httpCode == HTTP_CODE_OK) {
// get payload with http.getString();
Serial.println(httpCode);
// Serial.println(payload);
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", wlanHttp.errorToString(httpCode).c_str());
}
} else {
Serial.println("Error on HTTP request");
}
wlanHttp.end(); //Free the resources

QNetworkReply behavior againt local site with authentication

i'm using QNetworkReply in order to issue a simple GET request to my router interface. Basically if the post data is empty i issue a GET otherwise i will issue a POST. Let's stick with the GET
QString url=ui->lineEdit_url->text();
QString paras=ui->pTextEdit_paras->toPlainText();
qDebug()<< "paras" << paras;
QByteArray post_data;
post_data.append(paras);
QNetworkRequest request = QNetworkRequest(QUrl(url));
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
if(post_data.isEmpty())
{
//nam->head(request);
nam->get(request);
}
else
{
nam->post(request,post_data);
}
now with
...
connect(nam,
SIGNAL(finished(QNetworkReply*)),
this,
SLOT(finished(QNetworkReply*)));
...
void HttppostWindow::finished(QNetworkReply *reply)
{
if(reply->error() == QNetworkReply::NoError)
{
ui->textEdit_result->setText(QObject::tr(reply->readAll()));
}
else
{
ui->textEdit_result->setPlainText(reply->errorString());
}
}
i show the answer in the ui.
Right now the local interface asks for a login and a pw. The problem is that the retrieved text with the GET command is the one that the interface would show if the user would have insterted a wrong password (autentication failed please try again and so on).
Moreover with the code nam->head(request) i should be able to retrieve the header, but the content of replyAll is empty.
Any ideas?
After nam->head(request) you don't need to use reply->readAll().
Instead of this you should use methods like:
QByteArray rawHeader(const QByteArray &headerName) const;
QList<QByteArray> rawHeaderList() const;
const QList<RawHeaderPair> &rawHeaderPairs() const;
With this methods you can view content of your head request.
Also your sample code has memory leak. You should delete the reply whis reply->deleteLater() inside your finished slot.

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