1/****************************************************************************
2**
3** Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWebSockets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40/*!
41 \class QWebSocketServer
42
43 \inmodule QtWebSockets
44 \since 5.3
45
46 \brief Implements a WebSocket-based server.
47
48 It is modeled after QTcpServer, and behaves the same. So, if you know how to use QTcpServer,
49 you know how to use QWebSocketServer.
50 This class makes it possible to accept incoming WebSocket connections.
51 You can specify the port or have QWebSocketServer pick one automatically.
52 You can listen on a specific address or on all the machine's addresses.
53 Call listen() to have the server listen for incoming connections.
54
55 The newConnection() signal is then emitted each time a client connects to the server.
56 Call nextPendingConnection() to accept the pending connection as a connected QWebSocket.
57 The function returns a pointer to a QWebSocket in QAbstractSocket::ConnectedState that you can
58 use for communicating with the client.
59
60 If an error occurs, serverError() returns the type of error, and errorString() can be called
61 to get a human readable description of what happened.
62
63 When listening for connections, the address and port on which the server is listening are
64 available as serverAddress() and serverPort().
65
66 Calling close() makes QWebSocketServer stop listening for incoming connections.
67
68 QWebSocketServer currently does not support
69 \l {WebSocket Extensions} and
70 \l {WebSocket Subprotocols}.
71
72 \note When working with self-signed certificates, \l{Firefox bug 594502} prevents \l{Firefox} to
73 connect to a secure WebSocket server. To work around this problem, first browse to the
74 secure WebSocket server using HTTPS. FireFox will indicate that the certificate is invalid.
75 From here on, the certificate can be added to the exceptions. After this, the secure WebSockets
76 connection should work.
77
78 QWebSocketServer only supports version 13 of the WebSocket protocol, as outlined in \l{RFC 6455}.
79
80 There is a default connection handshake timeout of 10 seconds to avoid denial of service,
81 which can be customized using setHandshakeTimeout().
82
83 \sa {WebSocket Server Example}, QWebSocket
84*/
85
86/*!
87 \page echoserver.html example
88 \title WebSocket server example
89 \brief A sample WebSocket server echoing back messages sent to it.
90
91 \section1 Description
92 The echoserver example implements a WebSocket server that echoes back everything that is sent
93 to it.
94 \section1 Code
95 We start by creating a QWebSocketServer (`new QWebSocketServer()`). After the creation, we listen
96 on all local network interfaces (`QHostAddress::Any`) on the specified \a port.
97 \snippet echoserver/echoserver.cpp constructor
98 If listening is successful, we connect the `newConnection()` signal to the slot
99 `onNewConnection()`.
100 The `newConnection()` signal will be thrown whenever a new WebSocket client is connected to our
101 server.
102
103 \snippet echoserver/echoserver.cpp onNewConnection
104 When a new connection is received, the client QWebSocket is retrieved (`nextPendingConnection()`),
105 and the signals we are interested in are connected to our slots
106 (`textMessageReceived()`, `binaryMessageReceived()` and `disconnected()`).
107 The client socket is remembered in a list, in case we would like to use it later
108 (in this example, nothing is done with it).
109
110 \snippet echoserver/echoserver.cpp processTextMessage
111 Whenever `processTextMessage()` is triggered, we retrieve the sender, and if valid, send back the
112 original message (`sendTextMessage()`).
113 The same is done with binary messages.
114 \snippet echoserver/echoserver.cpp processBinaryMessage
115 The only difference is that the message now is a QByteArray instead of a QString.
116
117 \snippet echoserver/echoserver.cpp socketDisconnected
118 Whenever a socket is disconnected, we remove it from the clients list and delete the socket.
119 Note: it is best to use `deleteLater()` to delete the socket.
120*/
121
122/*!
123 \fn void QWebSocketServer::acceptError(QAbstractSocket::SocketError socketError)
124 This signal is emitted when the acceptance of a new connection results in an error.
125 The \a socketError parameter describes the type of error that occurred.
126
127 \sa pauseAccepting(), resumeAccepting()
128*/
129
130/*!
131 \fn void QWebSocketServer::serverError(QWebSocketProtocol::CloseCode closeCode)
132 This signal is emitted when an error occurs during the setup of a WebSocket connection.
133 The \a closeCode parameter describes the type of error that occurred
134
135 \sa errorString()
136*/
137
138/*!
139 \fn void QWebSocketServer::newConnection()
140 This signal is emitted every time a new connection is available.
141
142 \sa hasPendingConnections(), nextPendingConnection()
143*/
144
145/*!
146 \fn void QWebSocketServer::closed()
147 This signal is emitted when the server closed its connection.
148
149 \sa close()
150*/
151
152/*!
153 \fn void QWebSocketServer::originAuthenticationRequired(QWebSocketCorsAuthenticator *authenticator)
154 This signal is emitted when a new connection is requested.
155 The slot connected to this signal should indicate whether the origin
156 (which can be determined by the origin() call) is allowed in the \a authenticator object
157 (by issuing \l{QWebSocketCorsAuthenticator::}{setAllowed()}).
158
159 If no slot is connected to this signal, all origins will be accepted by default.
160
161 \note It is not possible to use a QueuedConnection to connect to
162 this signal, as the connection will always succeed.
163*/
164
165/*!
166 \fn void QWebSocketServer::peerVerifyError(const QSslError &error)
167
168 QWebSocketServer can emit this signal several times during the SSL handshake,
169 before encryption has been established, to indicate that an error has
170 occurred while establishing the identity of the peer. The \a error is
171 usually an indication that QWebSocketServer is unable to securely identify the
172 peer.
173
174 This signal provides you with an early indication when something is wrong.
175 By connecting to this signal, you can manually choose to tear down the
176 connection from inside the connected slot before the handshake has
177 completed. If no action is taken, QWebSocketServer will proceed to emitting
178 QWebSocketServer::sslErrors().
179
180 \sa sslErrors()
181*/
182
183/*!
184 \fn void QWebSocketServer::sslErrors(const QList<QSslError> &errors)
185
186 QWebSocketServer emits this signal after the SSL handshake to indicate that one
187 or more errors have occurred while establishing the identity of the
188 peer. The errors are usually an indication that QWebSocketServer is unable to
189 securely identify the peer. Unless any action is taken, the connection
190 will be dropped after this signal has been emitted.
191
192 \a errors contains one or more errors that prevent QSslSocket from
193 verifying the identity of the peer.
194
195 \sa peerVerifyError()
196*/
197
198/*!
199 \fn void QWebSocketServer::preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator)
200 \since 5.8
201
202 QWebSocketServer emits this signal when it negotiates a PSK ciphersuite, and
203 therefore a PSK authentication is then required.
204
205 When using PSK, the client must send to the server a valid identity and a
206 valid pre shared key, in order for the SSL handshake to continue.
207 Applications can provide this information in a slot connected to this
208 signal, by filling in the passed \a authenticator object according to their
209 needs.
210
211 \note Ignoring this signal, or failing to provide the required credentials,
212 will cause the handshake to fail, and therefore the connection to be aborted.
213
214 \note The \a authenticator object is owned by the socket and must not be
215 deleted by the application.
216
217 \sa QSslPreSharedKeyAuthenticator
218 \sa QSslSocket::preSharedKeyAuthenticationRequired()
219*/
220
221/*!
222 \enum QWebSocketServer::SslMode
223 Indicates whether the server operates over wss (SecureMode) or ws (NonSecureMode)
224
225 \value SecureMode The server operates in secure mode (over wss)
226 \value NonSecureMode The server operates in non-secure mode (over ws)
227 */
228
229#include "qwebsocketprotocol.h"
230#include "qwebsocket.h"
231#include "qwebsocketserver.h"
232#include "qwebsocketserver_p.h"
233
234#include <QtNetwork/QTcpServer>
235#include <QtNetwork/QTcpSocket>
236#include <QtNetwork/QNetworkProxy>
237
238#ifndef QT_NO_SSL
239#include <QtNetwork/QSslConfiguration>
240#endif
241
242QT_BEGIN_NAMESPACE
243
244/*!
245 Constructs a new QWebSocketServer with the given \a serverName.
246 The \a serverName will be used in the HTTP handshake phase to identify the server.
247 It can be empty, in which case no server name will be sent to the client.
248 The \a secureMode parameter indicates whether the server operates over wss (\l{SecureMode})
249 or over ws (\l{NonSecureMode}).
250
251 \a parent is passed to the QObject constructor.
252 */
253QWebSocketServer::QWebSocketServer(const QString &serverName, SslMode secureMode,
254 QObject *parent) :
255 QObject(*(new QWebSocketServerPrivate(serverName,
256 #ifndef QT_NO_SSL
257 (secureMode == SecureMode) ?
258 QWebSocketServerPrivate::SecureMode :
259 QWebSocketServerPrivate::NonSecureMode
260 #else
261 QWebSocketServerPrivate::NonSecureMode
262 #endif
263 )), parent)
264{
265#ifdef QT_NO_SSL
266 Q_UNUSED(secureMode)
267#endif
268 Q_D(QWebSocketServer);
269 d->init();
270}
271
272/*!
273 Destroys the QWebSocketServer object. If the server is listening for connections,
274 the socket is automatically closed.
275 Any client \l{QWebSocket}s that are still queued are closed and deleted.
276
277 \sa close()
278 */
279QWebSocketServer::~QWebSocketServer()
280{
281 Q_D(QWebSocketServer);
282 d->close(aboutToDestroy: true);
283}
284
285/*!
286 Closes the server. The server will no longer listen for incoming connections.
287 */
288void QWebSocketServer::close()
289{
290 Q_D(QWebSocketServer);
291 d->close();
292}
293
294/*!
295 Returns a human readable description of the last error that occurred.
296 If no error occurred, an empty string is returned.
297
298 \sa serverError()
299*/
300QString QWebSocketServer::errorString() const
301{
302 Q_D(const QWebSocketServer);
303 return d->errorString();
304}
305
306/*!
307 Returns true if the server has pending connections; otherwise returns false.
308
309 \sa nextPendingConnection(), setMaxPendingConnections()
310 */
311bool QWebSocketServer::hasPendingConnections() const
312{
313 Q_D(const QWebSocketServer);
314 return d->hasPendingConnections();
315}
316
317/*!
318 Returns true if the server is currently listening for incoming connections;
319 otherwise returns false. If listening fails, error() will return the reason.
320
321 \sa listen(), error()
322 */
323bool QWebSocketServer::isListening() const
324{
325 Q_D(const QWebSocketServer);
326 return d->isListening();
327}
328
329/*!
330 Tells the server to listen for incoming connections on address \a address and port \a port.
331 If \a port is 0, a port is chosen automatically.
332 If \a address is QHostAddress::Any, the server will listen on all network interfaces.
333
334 Returns true on success; otherwise returns false.
335
336 \sa isListening()
337 */
338bool QWebSocketServer::listen(const QHostAddress &address, quint16 port)
339{
340 Q_D(QWebSocketServer);
341 return d->listen(address, port);
342}
343
344/*!
345 Returns the maximum number of pending accepted connections. The default is 30.
346
347 \sa setMaxPendingConnections(), hasPendingConnections()
348 */
349int QWebSocketServer::maxPendingConnections() const
350{
351 Q_D(const QWebSocketServer);
352 return d->maxPendingConnections();
353}
354
355/*!
356 \fn std::chrono::milliseconds QWebSocketServer::handshakeTimeout() const
357 Returns the handshake timeout for new connections in milliseconds.
358
359 The default is 10 seconds. If a peer uses more time to complete the
360 handshake their connection is closed.
361
362 \sa setHandshakeTimeout(), handshakeTimeoutMS()
363 \since 5.14
364 */
365
366/*!
367 Returns the handshake timeout for new connections in milliseconds.
368
369 The default is 10 seconds. If a peer uses more time to complete the
370 handshake their connection is closed.
371
372 \sa setHandshakeTimeout(), handshakeTimeout()
373 \since 5.14
374 */
375int QWebSocketServer::handshakeTimeoutMS() const
376{
377 Q_D(const QWebSocketServer);
378 return d->handshakeTimeout();
379}
380
381/*!
382 Returns the next pending connection as a connected QWebSocket object.
383 QWebSocketServer does not take ownership of the returned QWebSocket object.
384 It is up to the caller to delete the object explicitly when it will no longer be used,
385 otherwise a memory leak will occur.
386 nullptr is returned if this function is called when there are no pending connections.
387
388 Note: The returned QWebSocket object cannot be used from another thread.
389
390 \sa hasPendingConnections()
391*/
392QWebSocket *QWebSocketServer::nextPendingConnection()
393{
394 Q_D(QWebSocketServer);
395 return d->nextPendingConnection();
396}
397
398/*!
399 Pauses incoming new connections. Queued connections will remain in queue.
400 \sa resumeAccepting()
401 */
402void QWebSocketServer::pauseAccepting()
403{
404 Q_D(QWebSocketServer);
405 d->pauseAccepting();
406}
407
408#ifndef QT_NO_NETWORKPROXY
409/*!
410 Returns the network proxy for this server. By default QNetworkProxy::DefaultProxy is used.
411
412 \sa setProxy()
413*/
414QNetworkProxy QWebSocketServer::proxy() const
415{
416 Q_D(const QWebSocketServer);
417 return d->proxy();
418}
419
420/*!
421 Sets the explicit network proxy for this server to \a networkProxy.
422
423 To disable the use of a proxy, use the QNetworkProxy::NoProxy proxy type:
424
425 \code
426 server->setProxy(QNetworkProxy::NoProxy);
427 \endcode
428
429 \sa proxy()
430*/
431void QWebSocketServer::setProxy(const QNetworkProxy &networkProxy)
432{
433 Q_D(QWebSocketServer);
434 d->setProxy(networkProxy);
435}
436#endif
437
438#ifndef QT_NO_SSL
439/*!
440 Sets the SSL configuration for the QWebSocketServer to \a sslConfiguration.
441 This method has no effect if QWebSocketServer runs in non-secure mode
442 (QWebSocketServer::NonSecureMode).
443
444 \sa sslConfiguration(), SslMode
445 */
446void QWebSocketServer::setSslConfiguration(const QSslConfiguration &sslConfiguration)
447{
448 Q_D(QWebSocketServer);
449 d->setSslConfiguration(sslConfiguration);
450}
451
452/*!
453 Returns the SSL configuration used by the QWebSocketServer.
454 If the server is not running in secure mode (QWebSocketServer::SecureMode),
455 this method returns QSslConfiguration::defaultConfiguration().
456
457 \sa setSslConfiguration(), SslMode, QSslConfiguration::defaultConfiguration()
458 */
459QSslConfiguration QWebSocketServer::sslConfiguration() const
460{
461 Q_D(const QWebSocketServer);
462 return d->sslConfiguration();
463}
464#endif
465
466/*!
467 Resumes accepting new connections.
468 \sa pauseAccepting()
469 */
470void QWebSocketServer::resumeAccepting()
471{
472 Q_D(QWebSocketServer);
473 d->resumeAccepting();
474}
475
476/*!
477 Sets the server name that will be used during the HTTP handshake phase to the given
478 \a serverName.
479 The \a serverName can be empty, in which case an empty server name will be sent to the client.
480 Existing connected clients will not be notified of this change, only newly connecting clients
481 will see this new name.
482 */
483void QWebSocketServer::setServerName(const QString &serverName)
484{
485 Q_D(QWebSocketServer);
486 d->setServerName(serverName);
487}
488
489/*!
490 Returns the server name that is used during the http handshake phase.
491 */
492QString QWebSocketServer::serverName() const
493{
494 Q_D(const QWebSocketServer);
495 return d->serverName();
496}
497
498/*!
499 Returns the server's address if the server is listening for connections; otherwise returns
500 QHostAddress::Null.
501
502 \sa serverPort(), listen()
503 */
504QHostAddress QWebSocketServer::serverAddress() const
505{
506 Q_D(const QWebSocketServer);
507 return d->serverAddress();
508}
509
510/*!
511 Returns the secure mode the server is running in.
512
513 \sa QWebSocketServer(), SslMode
514 */
515QWebSocketServer::SslMode QWebSocketServer::secureMode() const
516{
517#ifndef QT_NO_SSL
518 Q_D(const QWebSocketServer);
519 return (d->secureMode() == QWebSocketServerPrivate::SecureMode) ?
520 QWebSocketServer::SecureMode : QWebSocketServer::NonSecureMode;
521#else
522 return QWebSocketServer::NonSecureMode;
523#endif
524}
525
526/*!
527 Returns an error code for the last error that occurred.
528 If no error occurred, QWebSocketProtocol::CloseCodeNormal is returned.
529
530 \sa errorString()
531 */
532QWebSocketProtocol::CloseCode QWebSocketServer::error() const
533{
534 Q_D(const QWebSocketServer);
535 return d->serverError();
536}
537
538/*!
539 Returns the server's port if the server is listening for connections; otherwise returns 0.
540
541 \sa serverAddress(), listen()
542 */
543quint16 QWebSocketServer::serverPort() const
544{
545 Q_D(const QWebSocketServer);
546 return d->serverPort();
547}
548
549/*!
550 Returns a URL clients can use to connect to this server if the server is listening for connections.
551 Otherwise an invalid URL is returned.
552
553 \sa serverPort(), serverAddress(), listen()
554 */
555QUrl QWebSocketServer::serverUrl() const
556{
557 QUrl url;
558
559 if (!isListening()) {
560 return url;
561 }
562
563 switch (secureMode()) {
564 case NonSecureMode:
565 url.setScheme(QStringLiteral("ws"));
566 break;
567 #ifndef QT_NO_SSL
568 case SecureMode:
569 url.setScheme(QStringLiteral("wss"));
570 break;
571 #endif
572 }
573
574 url.setPort(serverPort());
575
576 if (serverAddress() == QHostAddress(QHostAddress::Any)) {
577 // NOTE: On Windows at least, clients cannot connect to QHostAddress::Any
578 // so in that case we always return LocalHost instead.
579 url.setHost(host: QHostAddress(QHostAddress::LocalHost).toString());
580 } else {
581 url.setHost(host: serverAddress().toString());
582 }
583
584 return url;
585}
586
587/*!
588 Sets the maximum number of pending accepted connections to \a numConnections.
589 WebSocketServer will accept no more than \a numConnections incoming connections before
590 nextPendingConnection() is called.
591 By default, the limit is 30 pending connections.
592
593 QWebSocketServer will emit the error() signal with
594 the QWebSocketProtocol::CloseCodeAbnormalDisconnection close code
595 when the maximum of connections has been reached.
596 The WebSocket handshake will fail and the socket will be closed.
597
598 \sa maxPendingConnections(), hasPendingConnections()
599 */
600void QWebSocketServer::setMaxPendingConnections(int numConnections)
601{
602 Q_D(QWebSocketServer);
603 d->setMaxPendingConnections(numConnections);
604}
605
606/*!
607 \fn void QWebSocketServer::setHandshakeTimeout(std::chrono::milliseconds msec)
608 Sets the handshake timeout for new connections to \a msec milliseconds.
609
610 By default this is set to 10 seconds. If a peer uses more time to
611 complete the handshake, their connection is closed. You can pass a
612 negative value (e.g. -1) to disable the timeout.
613
614 \sa handshakeTimeout(), handshakeTimeoutMS()
615 \since 5.14
616 */
617
618/*!
619 \overload
620*/
621void QWebSocketServer::setHandshakeTimeout(int msec)
622{
623 Q_D(QWebSocketServer);
624 d->setHandshakeTimeout(msec);
625}
626
627#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
628/*!
629 Sets the socket descriptor this server should use when listening for incoming connections to
630 \a socketDescriptor.
631
632 Returns true if the socket is set successfully; otherwise returns false.
633 The socket is assumed to be in listening state.
634
635 \sa socketDescriptor(), isListening()
636 \since 5.3
637 */
638bool QWebSocketServer::setSocketDescriptor(qintptr socketDescriptor)
639{
640 Q_D(QWebSocketServer);
641 return d->setSocketDescriptor(socketDescriptor);
642}
643
644/*!
645 Returns the native socket descriptor the server uses to listen for incoming instructions,
646 or -1 if the server is not listening.
647 If the server is using QNetworkProxy, the returned descriptor may not be usable with
648 native socket functions.
649
650 \sa setSocketDescriptor(), isListening()
651 \since 5.3
652 */
653qintptr QWebSocketServer::socketDescriptor() const
654{
655 Q_D(const QWebSocketServer);
656 return d->socketDescriptor();
657}
658
659#else // ### Qt 6: Remove leftovers
660/*!
661 \deprecated
662
663 Sets the socket descriptor this server should use when listening for incoming connections to
664 \a socketDescriptor.
665
666 Returns true if the socket is set successfully; otherwise returns false.
667 The socket is assumed to be in listening state.
668
669 \sa socketDescriptor(), setSocketDescriptor(), nativeDescriptor(), isListening()
670 \since 5.3
671 */
672bool QWebSocketServer::setSocketDescriptor(int socketDescriptor)
673{
674 return setNativeDescriptor(socketDescriptor);
675}
676
677/*!
678 \deprecated
679
680 Returns the native socket descriptor the server uses to listen for incoming instructions,
681 or -1 if the server is not listening.
682 If the server is using QNetworkProxy, the returned descriptor may not be usable with
683 native socket functions.
684
685 \sa nativeDescriptor(), setNativeDescriptor(), setSocketDescriptor(), isListening()
686 \since 5.3
687 */
688int QWebSocketServer::socketDescriptor() const
689{
690 return int(nativeDescriptor());
691}
692
693/*!
694 Sets the socket descriptor this server should use when listening for incoming connections to
695 \a socketDescriptor.
696
697 Returns true if the socket is set successfully; otherwise returns false.
698 The socket is assumed to be in listening state.
699
700 \sa nativeDescriptor(), isListening()
701 \since 5.12
702 */
703bool QWebSocketServer::setNativeDescriptor(qintptr socketDescriptor)
704{
705 Q_D(QWebSocketServer);
706 return d->setSocketDescriptor(socketDescriptor);
707}
708
709/*!
710 Returns the native socket descriptor the server uses to listen for incoming instructions,
711 or -1 if the server is not listening.
712 If the server is using QNetworkProxy, the returned descriptor may not be usable with
713 native socket functions.
714
715 \sa setNativeDescriptor(), isListening()
716 \since 5.12
717 */
718qintptr QWebSocketServer::nativeDescriptor() const
719{
720 Q_D(const QWebSocketServer);
721 return d->socketDescriptor();
722}
723#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
724
725/*!
726 Returns a list of WebSocket versions that this server is supporting.
727 */
728QList<QWebSocketProtocol::Version> QWebSocketServer::supportedVersions() const
729{
730 Q_D(const QWebSocketServer);
731 return d->supportedVersions();
732}
733
734/*!
735 Upgrades a tcp \a socket to websocket.
736
737 The QWebSocketServer object will take ownership of the socket
738 object and delete it when appropriate.
739
740 \since 5.9
741*/
742void QWebSocketServer::handleConnection(QTcpSocket *socket) const
743{
744 Q_D(const QWebSocketServer);
745 d->handleConnection(pTcpSocket: socket);
746}
747
748QT_END_NAMESPACE
749

source code of qtwebsockets/src/websockets/qwebsocketserver.cpp