Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtcpserverconnection.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#include <private/qqmldebugserverconnection_p.h>
6#include <private/qqmldebugserver_p.h>
7
8#include <QtCore/qplugin.h>
9#include <QtNetwork/qtcpserver.h>
10#include <QtNetwork/qtcpsocket.h>
11
12QT_BEGIN_NAMESPACE
13
14class QTcpServerConnection : public QQmlDebugServerConnection
15{
16 Q_OBJECT
17 Q_DISABLE_COPY(QTcpServerConnection)
18
19public:
20 QTcpServerConnection();
21 ~QTcpServerConnection() override;
22
23 void setServer(QQmlDebugServer *server) override;
24 bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress) override;
25 bool setFileName(const QString &fileName, bool block) override;
26
27 bool isConnected() const override;
28 void disconnect() override;
29
30 void waitForConnection() override;
31 void flush() override;
32
33private:
34 void newConnection();
35 bool listen();
36
37 int m_portFrom = 0;
38 int m_portTo = 0;
39 bool m_block = false;
40 QString m_hostaddress;
41 QTcpSocket *m_socket = nullptr;
42 QTcpServer *m_tcpServer = nullptr;
43 QQmlDebugServer *m_debugServer = nullptr;
44};
45
46QTcpServerConnection::QTcpServerConnection() {}
47
48QTcpServerConnection::~QTcpServerConnection()
49{
50 if (isConnected())
51 disconnect();
52}
53
54void QTcpServerConnection::setServer(QQmlDebugServer *server)
55{
56 m_debugServer = server;
57}
58
59bool QTcpServerConnection::isConnected() const
60{
61 return m_socket && m_socket->state() == QTcpSocket::ConnectedState;
62}
63
64void QTcpServerConnection::disconnect()
65{
66 while (m_socket && m_socket->bytesToWrite() > 0) {
67 if (!m_socket->waitForBytesWritten()) {
68 qWarning("QML Debugger: Failed to send remaining %lld bytes on disconnect.",
69 m_socket->bytesToWrite());
70 break;
71 }
72 }
73
74 m_socket->deleteLater();
75 m_socket = nullptr;
76}
77
78bool QTcpServerConnection::setPortRange(int portFrom, int portTo, bool block,
79 const QString &hostaddress)
80{
81 m_portFrom = portFrom;
82 m_portTo = portTo;
83 m_block = block;
84 m_hostaddress = hostaddress;
85
86 return listen();
87}
88
89bool QTcpServerConnection::setFileName(const QString &fileName, bool block)
90{
91 Q_UNUSED(fileName);
92 Q_UNUSED(block);
93 return false;
94}
95
96void QTcpServerConnection::waitForConnection()
97{
98 m_tcpServer->waitForNewConnection(-1);
99}
100
101void QTcpServerConnection::flush()
102{
103 if (m_socket)
104 m_socket->flush();
105}
106
107bool QTcpServerConnection::listen()
108{
109 m_tcpServer = new QTcpServer(this);
110 QObject::connect(m_tcpServer, &QTcpServer::newConnection,
111 this, &QTcpServerConnection::newConnection);
112 QHostAddress hostaddress;
113 if (!m_hostaddress.isEmpty()) {
114 if (!hostaddress.setAddress(m_hostaddress)) {
115 hostaddress = QHostAddress::Any;
116 qDebug("QML Debugger: Incorrect host address provided. So accepting connections "
117 "from any host.");
118 }
119 } else {
120 hostaddress = QHostAddress::Any;
121 }
122 int port = m_portFrom;
123 do {
124 if (m_tcpServer->listen(hostaddress, port)) {
125 qDebug("QML Debugger: Waiting for connection on port %d...", port);
126 break;
127 }
128 ++port;
129 } while (port <= m_portTo);
130 if (port > m_portTo) {
131 if (m_portFrom == m_portTo)
132 qWarning("QML Debugger: Unable to listen to port %d.", m_portFrom);
133 else
134 qWarning("QML Debugger: Unable to listen to ports %d - %d.", m_portFrom, m_portTo);
135 return false;
136 } else {
137 return true;
138 }
139}
140
141void QTcpServerConnection::newConnection()
142{
143 if (m_socket && m_socket->peerPort()) {
144 qWarning("QML Debugger: Another client is already connected.");
145 QTcpSocket *faultyConnection = m_tcpServer->nextPendingConnection();
146 delete faultyConnection;
147 return;
148 }
149
150 delete m_socket;
151 m_socket = m_tcpServer->nextPendingConnection();
152 m_socket->setParent(this);
153 m_debugServer->setDevice(m_socket);
154}
155
156
158{
159 Q_OBJECT
160 Q_PLUGIN_METADATA(IID QQmlDebugServerConnectionFactory_iid FILE "qtcpserverconnection.json")
162public:
164};
165
166QQmlDebugServerConnection *QTcpServerConnectionFactory::create(const QString &key)
167{
168 return (key == QLatin1String("QTcpServerConnection") ? new QTcpServerConnection : nullptr);
169}
170
171QT_END_NAMESPACE
172
173#include "qtcpserverconnection.moc"