Update license headers and add new license files
[contrib/qtwebsockets.git] / src / imports / qmlwebsockets / qqmlwebsocketserver.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtWebSocket module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** In addition, as a special exception, Digia gives you certain additional
27 ** rights. These rights are described in the Digia Qt LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** $QT_END_LICENSE$
31 **
32 ****************************************************************************/
33
34 #include "qqmlwebsocketserver.h"
35 #include "qqmlwebsocket.h"
36
37 QT_USE_NAMESPACE
38
39 /*!
40     \qmltype WebSocketServer
41     \instantiates QQmlWebSocketServer
42
43     \inqmlmodule Qt.WebSockets
44     \ingroup websockets-qml
45     \brief QML interface to QWebSocketServer.
46 */
47
48 /*!
49   \qmlproperty QUrl WebSocketServer::url
50   Server url that client WebSockets can connect to. The url uses the \e ws:// scheme and includes the
51   port the server listens to and the host address of the server.
52   */
53
54 /*!
55   \qmlproperty QString WebSocketServer::host
56   The host address of the server. By default, localhost is used.
57   */
58
59 /*!
60   \qmlproperty int WebSocketServer::port
61   The port this server is listening on. By default, a port is chosen automatically.
62   */
63
64 /*!
65   \qmlproperty QString WebSocketServer::name
66   The name of this server used during the http handshake phase.
67   */
68
69 /*!
70   \qmlproperty QString WebSocketServer::errorString
71   The stringified error message in case an error occurred.
72   */
73
74 /*!
75   \qmlproperty bool WebSocketServer::listen
76   Set to true when the server should listen to client connections or false otherwise.
77   When set to true, the server will listen on the specified url defined by host and port
78   and, when accept is true, accepts incoming client connections. Otherwise the server is closed.
79   By default, the server is not listening.
80   */
81
82 /*!
83   \qmlproperty bool WebSocketServer::accept
84   Set to true to accept incoming client connections when the server is listening. When set to false,
85   incoming connections are rejected. By default, connections are accepted.
86   */
87
88 /*!
89   \qmlsignal WebSocketServer::clientConnected(WebSocket webSocket)
90   This signal is emitted when a client connects to this server.
91   */
92
93 QQmlWebSocketServer::QQmlWebSocketServer(QObject *parent)
94     : QObject(parent)
95     , m_host(QHostAddress(QHostAddress::LocalHost).toString())
96     , m_port(0)
97     , m_listen(false)
98     , m_accept(true)
99     , m_componentCompleted(true)
100 {
101 }
102
103 QQmlWebSocketServer::~QQmlWebSocketServer()
104 {
105
106 }
107
108 void QQmlWebSocketServer::classBegin()
109 {
110     m_componentCompleted = false;
111 }
112
113 void QQmlWebSocketServer::componentComplete()
114 {
115     init();
116     m_componentCompleted = true;
117 }
118
119 QUrl QQmlWebSocketServer::url() const
120 {
121     QUrl url;
122     url.setPort(m_port);
123     url.setHost(m_host);
124     url.setScheme("ws");
125     return url;
126 }
127
128 QString QQmlWebSocketServer::host() const
129 {
130     return m_host;
131 }
132
133 void QQmlWebSocketServer::setHost(const QString &host)
134 {
135     if (host == m_host) {
136         return;
137     }
138
139     m_host = host;
140     emit hostChanged(host);
141     emit urlChanged(url());
142
143     updateListening();
144 }
145
146 quint16 QQmlWebSocketServer::port() const
147 {
148     return m_port;
149 }
150
151 void QQmlWebSocketServer::setPort(quint16 port)
152 {
153     if (port == m_port) {
154         return;
155     }
156
157     m_port = port;
158     emit portChanged(port);
159     emit urlChanged(url());
160
161     if (m_componentCompleted && m_server->isListening()) {
162         updateListening();
163     }
164 }
165
166 QString QQmlWebSocketServer::errorString() const
167 {
168     return m_server ? m_server->errorString() : tr("QQmlWebSocketServer is not ready.");
169 }
170
171 QString QQmlWebSocketServer::name() const
172 {
173     return m_name;
174 }
175
176 void QQmlWebSocketServer::setName(const QString &name)
177 {
178     if (name == m_name) {
179         return;
180     }
181
182     m_name = name;
183     emit nameChanged(name);
184
185     if (m_componentCompleted) {
186         init();
187     }
188 }
189
190 bool QQmlWebSocketServer::listen() const
191 {
192     return m_listen;
193 }
194
195 void QQmlWebSocketServer::setListen(bool listen)
196 {
197     if (listen == m_listen) {
198         return;
199     }
200
201     m_listen = listen;
202     emit listenChanged(listen);
203
204     updateListening();
205 }
206
207 bool QQmlWebSocketServer::accept() const
208 {
209     return m_accept;
210 }
211
212 void QQmlWebSocketServer::setAccept(bool accept)
213 {
214     if (accept == m_accept) {
215         return;
216     }
217
218     m_accept = accept;
219     emit acceptChanged(accept);
220
221     if (m_componentCompleted) {
222         if (!accept) {
223             m_server->pauseAccepting();
224         } else {
225             m_server->resumeAccepting();
226         }
227     }
228 }
229
230 void QQmlWebSocketServer::init()
231 {
232     // TODO: add support for wss, requires ssl configuration to be set from QML - realistic?
233     m_server.reset(new QWebSocketServer(m_name, QWebSocketServer::NonSecureMode));
234
235     connect(m_server.data(), &QWebSocketServer::newConnection,
236             this, &QQmlWebSocketServer::newConnection);
237     connect(m_server.data(), &QWebSocketServer::serverError,
238             this, &QQmlWebSocketServer::serverError);
239     connect(m_server.data(), &QWebSocketServer::closed,
240             this, &QQmlWebSocketServer::closed);
241
242     updateListening();
243 }
244
245 void QQmlWebSocketServer::updateListening()
246 {
247     if (!m_server) {
248         return;
249     }
250
251     if (m_server->isListening()) {
252         m_server->close();
253     }
254
255     if (!m_listen || !m_server->listen(QHostAddress(m_host), m_port)) {
256         return;
257     }
258     setPort(m_server->serverPort());
259     setHost(m_server->serverAddress().toString());
260 }
261
262 void QQmlWebSocketServer::newConnection()
263 {
264     emit clientConnected(new QQmlWebSocket(m_server->nextPendingConnection(), this));
265 }
266
267 void QQmlWebSocketServer::serverError()
268 {
269     emit errorStringChanged(errorString());
270 }
271
272 void QQmlWebSocketServer::closed()
273 {
274     setListen(false);
275 }
276