summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikhail Svetkin <mikhail.svetkin@gmail.com>2019-07-06 19:40:42 +0200
committerMikhail Svetkin <mikhail.svetkin@gmail.com>2019-07-09 20:33:56 +0200
commitfb551f9845126ba991ecc13455fcc67bc42c0fe1 (patch)
treec13138916e1f43d09d6f49e70a083e5386d1b26c
parentec8a569b68179c193ee2af3f91b612d5be81a355 (diff)
QAbstractHttpServer: Simplify handleNewConection/handleReadyRead
Remove usage of QObjectUserData. Remove usage of QHash of QHttpServerRequest. Change-Id: I8a6c44bcfefc12c841ae67562e9bbec10f6ab9bf Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/httpserver/qabstracthttpserver.cpp57
-rw-r--r--src/httpserver/qabstracthttpserver_p.h9
-rw-r--r--src/httpserver/qhttpserverrequest.cpp2
-rw-r--r--src/httpserver/qhttpserverrequest.h4
-rw-r--r--tests/auto/qabstracthttpserver/tst_qabstracthttpserver.cpp22
5 files changed, 44 insertions, 50 deletions
diff --git a/src/httpserver/qabstracthttpserver.cpp b/src/httpserver/qabstracthttpserver.cpp
index f21c8a9..f31e7b8 100644
--- a/src/httpserver/qabstracthttpserver.cpp
+++ b/src/httpserver/qabstracthttpserver.cpp
@@ -47,15 +47,8 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcHttpServer, "qt.httpserver")
-#if !defined(QT_NO_USERDATA)
-QAtomicInt QAbstractHttpServerPrivate::userDataId = -1;
-#endif
-
QAbstractHttpServerPrivate::QAbstractHttpServerPrivate()
{
-#if !defined(QT_NO_USERDATA)
- userDataId.testAndSetRelaxed(-1, int(QObject::registerUserData()));
-#endif
}
void QAbstractHttpServerPrivate::handleNewConnections()
@@ -63,52 +56,47 @@ void QAbstractHttpServerPrivate::handleNewConnections()
Q_Q(QAbstractHttpServer);
auto tcpServer = qobject_cast<QTcpServer *>(q->sender());
Q_ASSERT(tcpServer);
- while (auto *socket = tcpServer->nextPendingConnection()) {
+ while (auto socket = tcpServer->nextPendingConnection()) {
auto request = new QHttpServerRequest; // TODO own tcp server could pre-allocate it
http_parser_init(&request->d->httpParser, HTTP_REQUEST);
- connect(socket, &QTcpSocket::readyRead, this, &QAbstractHttpServerPrivate::handleReadyRead);
- socket->connect(socket, &QTcpSocket::disconnected, &QObject::deleteLater);
-#if !defined(QT_NO_USERDATA)
- socket->setUserData(uint(userDataId), request);
-#else
- QObject::connect(socket, &QTcpSocket::destroyed, [&]() {
- requests.remove(socket);
+
+ QObject::connect(socket, &QTcpSocket::readyRead, q_ptr,
+ [this, request, socket] () {
+ handleReadyRead(socket, request);
+ });
+
+ QObject::connect(socket, &QTcpSocket::disconnected, &QObject::deleteLater);
+ QObject::connect(socket, &QObject::destroyed, [request] () {
+ delete request;
});
- requests.insert(socket, request);
-#endif
}
}
-void QAbstractHttpServerPrivate::handleReadyRead()
+void QAbstractHttpServerPrivate::handleReadyRead(QTcpSocket *socket,
+ QHttpServerRequest *request)
{
Q_Q(QAbstractHttpServer);
- auto socket = qobject_cast<QTcpSocket *>(q->sender());
Q_ASSERT(socket);
-#if !defined(QT_NO_USERDATA)
- auto request = static_cast<QHttpServerRequest *>(socket->userData(uint(userDataId)));
-#else
- auto request = requests[socket];
-#endif
- auto &requestPrivate = request->d;
+ Q_ASSERT(request);
if (!socket->isTransactionStarted())
socket->startTransaction();
- if (requestPrivate->state == QHttpServerRequestPrivate::State::OnMessageComplete)
- requestPrivate->clear();
+ if (request->d->state == QHttpServerRequestPrivate::State::OnMessageComplete)
+ request->d->clear();
- if (!requestPrivate->parse(socket)) {
+ if (!request->d->parse(socket)) {
socket->disconnect();
return;
}
- if (!requestPrivate->httpParser.upgrade &&
- requestPrivate->state != QHttpServerRequestPrivate::State::OnMessageComplete)
+ if (!request->d->httpParser.upgrade &&
+ request->d->state != QHttpServerRequestPrivate::State::OnMessageComplete)
return; // Partial read
- if (requestPrivate->httpParser.upgrade) { // Upgrade
- const auto &headers = requestPrivate->headers;
- const auto upgradeHash = requestPrivate->headerHash(QByteArrayLiteral("upgrade"));
+ if (request->d->httpParser.upgrade) { // Upgrade
+ const auto &headers = request->d->headers;
+ const auto upgradeHash = request->d->headerHash(QByteArrayLiteral("upgrade"));
const auto it = headers.find(upgradeHash);
if (it != headers.end()) {
#if defined(QT_WEBSOCKETS_LIB)
@@ -116,8 +104,7 @@ void QAbstractHttpServerPrivate::handleReadyRead()
static const auto signal = QMetaMethod::fromSignal(
&QAbstractHttpServer::newWebSocketConnection);
if (q->isSignalConnected(signal)) {
- disconnect(socket, &QTcpSocket::readyRead,
- this, &QAbstractHttpServerPrivate::handleReadyRead);
+ QObject::disconnect(socket, &QTcpSocket::readyRead, nullptr, nullptr);
socket->rollbackTransaction();
websocketServer.handleConnection(socket);
Q_EMIT socket->readyRead();
diff --git a/src/httpserver/qabstracthttpserver_p.h b/src/httpserver/qabstracthttpserver_p.h
index 4a0cd4b..69732ff 100644
--- a/src/httpserver/qabstracthttpserver_p.h
+++ b/src/httpserver/qabstracthttpserver_p.h
@@ -67,14 +67,9 @@ public:
};
#endif // defined(QT_WEBSOCKETS_LIB)
-#if !defined(QT_NO_USERDATA)
- static QAtomicInt userDataId;
-#else
- QHash<QTcpSocket *, QHttpServerRequest *> requests;
-#endif
-
void handleNewConnections();
- void handleReadyRead();
+ void handleReadyRead(QTcpSocket *socket,
+ QHttpServerRequest *request);
};
QT_END_NAMESPACE
diff --git a/src/httpserver/qhttpserverrequest.cpp b/src/httpserver/qhttpserverrequest.cpp
index 7500ede..4b0b1e1 100644
--- a/src/httpserver/qhttpserverrequest.cpp
+++ b/src/httpserver/qhttpserverrequest.cpp
@@ -249,12 +249,10 @@ int QHttpServerRequestPrivate::onChunkComplete(http_parser *httpParser)
}
QHttpServerRequest::QHttpServerRequest() :
- QObjectUserData(),
d(new QHttpServerRequestPrivate)
{}
QHttpServerRequest::QHttpServerRequest(const QHttpServerRequest &other) :
- QObjectUserData(),
d(other.d)
{}
diff --git a/src/httpserver/qhttpserverrequest.h b/src/httpserver/qhttpserverrequest.h
index 3d1210c..11754b2 100644
--- a/src/httpserver/qhttpserverrequest.h
+++ b/src/httpserver/qhttpserverrequest.h
@@ -44,7 +44,7 @@ class QString;
class QTcpSocket;
class QHttpServerRequestPrivate;
-class Q_HTTPSERVER_EXPORT QHttpServerRequest : public QObjectUserData
+class Q_HTTPSERVER_EXPORT QHttpServerRequest
{
friend class QAbstractHttpServerPrivate;
friend class QHttpServerResponse;
@@ -52,7 +52,7 @@ class Q_HTTPSERVER_EXPORT QHttpServerRequest : public QObjectUserData
Q_GADGET
public:
- ~QHttpServerRequest() override;
+ virtual ~QHttpServerRequest();
enum class Method
{
diff --git a/tests/auto/qabstracthttpserver/tst_qabstracthttpserver.cpp b/tests/auto/qabstracthttpserver/tst_qabstracthttpserver.cpp
index 4f7f10e..bdb40a8 100644
--- a/tests/auto/qabstracthttpserver/tst_qabstracthttpserver.cpp
+++ b/tests/auto/qabstracthttpserver/tst_qabstracthttpserver.cpp
@@ -147,12 +147,26 @@ void tst_QAbstractHttpServer::websocket()
auto tcpServer = new QTcpServer;
tcpServer->listen();
server.bind(tcpServer);
- QWebSocket socket;
- const QUrl url(QString::fromLatin1("ws://localhost:%1").arg(tcpServer->serverPort()));
- socket.open(url);
+ auto makeWebSocket = [this, tcpServer] () mutable {
+ auto s = new QWebSocket(QString::fromUtf8(""),
+ QWebSocketProtocol::VersionLatest,
+ this);
+ const QUrl url(QString::fromLatin1("ws://localhost:%1").arg(tcpServer->serverPort()));
+ s->open(url);
+ return s;
+ };
+
+ // We have to send two requests to make sure that swapping between
+ // QTcpSocket and QWebSockets works correctly
+ auto s1 = makeWebSocket();
+ auto s2 = makeWebSocket();
+
QSignalSpy newConnectionSpy(&server, &HttpServer::newWebSocketConnection);
- QTRY_COMPARE(newConnectionSpy.count(), 1);
+ QTRY_COMPARE(newConnectionSpy.count(), 2);
+ delete server.nextPendingWebSocketConnection();
delete server.nextPendingWebSocketConnection();
+ delete s1;
+ delete s2;
#endif // defined(QT_WEBSOCKETS_LIB)
}