Too many "HTTP 400 – Bad Request"
-
Hello,
Our team is developing application using Qt 4.8.2. This application periodically makes many http and https requests to our servers and we found that there are a lots of "400" status codes in the log-files of our web servers (nginx). There are much more such bad requests than "good" requests.
We've found that our app often opens "empty" connection, i mean that it establishes tcp connection with web server and do not send anything to this socket.
Is it a bug or is it a normal behavior and how can it be handled?
-
here is a code of test app that reproduce this issue.
file main.cpp:
[code]
#include <QCoreApplication>
#include <QTimer>
#include <Sample.h>
#include <Windows.h>int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);Sample obj;
// QTimer::singleShot(10000, &obj, SLOT(onTimer()));
for (int i = 0; i < 3; i++) { obj.makeRequest(); } while(true) { Sleep(1000); obj.makeRequest(); } int ret = a.exec(); return ret;
}
[/code]file sample.h
[code]
#ifndef SAMPLE_H
#define SAMPLE_H#include <QObject>
#include <QList>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QSslError>class Sample : public QObject
{
Q_OBJECT
public:
explicit Sample(QObject *parent = 0);void startTest(); void makeRequest();
signals:
public slots:
void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
void onTimer();
void onRequestFinish();
void onError(QNetworkReply::NetworkError error);private:
QNetworkAccessManager *_manager;};
#endif // SAMPLE_H
[/code]
file sample.cpp
[code]
#include <Sample.h>#include <QCoreApplication>
#include <QDebug>
#include <QUrl>
#include <QtNetwork/QNetworkRequest>Sample::Sample(QObject parent)
: QObject(parent), _manager(new QNetworkAccessManager(this))
{
connect(this->_manager, SIGNAL(sslErrors(QNetworkReply, const QList<QSslError>&)),
this, SLOT(sslErrors(QNetworkReply *, const QList<QSslError>&)));
}void Sample::startTest()
{
makeRequest();
}
[code]
void Sample::makeRequest()
{
QUrl request("https://localhost:8443/restapi?method=games.getMaintenance");QNetworkReply *reply = (1 == 1) ? this->_manager->get(QNetworkRequest(request)) : this->_manager->post(QNetworkRequest(request), request.encodedQuery()); connect(reply, SIGNAL(finished()), this, SLOT(onRequestFinish())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError))); qDebug() << "makeRequest" << request;
}
void Sample::onRequestFinish()
{
qDebug() << "onRequestFinish";QNetworkReply *reply = qobject_cast<QNetworkReply*>(QObject::sender()); reply->deleteLater(); QString response = QString::fromUtf8(reply->readAll()); QNetworkReply::NetworkError error = reply->error(); qDebug() << response << error;
}
void Sample::onError(QNetworkReply::NetworkError error)
{
qDebug() << "error" << error;
}void Sample::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
{
qDebug() << "sslErrors";
Q_FOREACH(QSslError error, errors) {
qDebug() << error;
}reply->ignoreSslErrors();
}
void Sample::onTimer()
{
QCoreApplication::quit();
}[/code]
-
Please use "code" tags around your code to make it readable...
-
Found this:
[url]https://bugreports.qt-project.org/browse/QTBUG-14783?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel[/url]Is there a way to force desktop application not to open additional parallel channels (tcp connections) if it is not really necessary? Especially for the SSL.
-
I noticed one big problem; you schedule all your requests in main. Before you start the event-loop (the exec line).
Please try to restructure your code to
a) avoid a sleep() call. Really, you can't have Sleep() in your code.
b) make the requests being called be called in the event-loop. I suggest using QTimer::singleShot()