943af5607002fe5fd99816298e9591653efb6565
[contrib/qtwebsockets.git] / src / websockets / qwebsocket.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 /*!
43     \class QWebSocket
44
45     \inmodule QtWebSockets
46     \brief Implements a TCP socket that talks the websocket protocol.
47
48     WebSockets is a web technology providing full-duplex communications channels over a single TCP connection.
49     The WebSocket protocol was standardized by the IETF as \l {http://tools.ietf.org/html/rfc6455} {RFC 6455} in 2011.
50     QWebSocket can both be used in a client application and server application.
51
52     This class was modeled after QAbstractSocket.
53
54     \sa QAbstractSocket, QTcpSocket
55
56     \sa {QWebSocket client example}
57 */
58
59 /*!
60     \page echoclient.html example
61     \title QWebSocket client example
62     \brief A sample websocket client that sends a message and displays the message that it receives back.
63
64     \section1 Description
65     The EchoClient example implements a web socket client that sends a message to a websocket server and dumps the answer that it gets back.
66     This example should ideally be used with the EchoServer example.
67     \section1 Code
68     We start by connecting to the `connected()` signal.
69     \snippet echoclient/echoclient.cpp constructor
70     After the connection, we open the socket to the given \a url.
71
72     \snippet echoclient/echoclient.cpp onConnected
73     When the client is connected successfully, we connect to the `onTextMessageReceived()` signal, and send out "Hello, world!".
74     If connected with the EchoServer, we will receive the same message back.
75
76     \snippet echoclient/echoclient.cpp onTextMessageReceived
77     Whenever a message is received, we write it out.
78 */
79
80 /*!
81   \fn void QWebSocket::connected()
82   \brief Emitted when a connection is successfully established.
83   A connection is successfully established when the socket is connected
84   and the handshake was successful.
85   \sa open(), disconnected()
86 */
87 /*!
88   \fn void QWebSocket::disconnected()
89   \brief Emitted when the socket is disconnected.
90   \sa close(), connected()
91 */
92 /*!
93     \fn void QWebSocket::aboutToClose()
94
95     This signal is emitted when the socket is about to close.
96     Connect this signal if you have operations that need to be performed before the socket closes
97     (e.g., if you have data in a separate buffer that needs to be written to the device).
98
99     \sa close()
100  */
101 /*!
102 \fn void QWebSocket::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
103
104 This signal can be emitted when a \a proxy that requires
105 authentication is used. The \a authenticator object can then be
106 filled in with the required details to allow authentication and
107 continue the connection.
108
109 \note It is not possible to use a QueuedConnection to connect to
110 this signal, as the connection will fail if the authenticator has
111 not been filled in with new information when the signal returns.
112
113 \sa QAuthenticator, QNetworkProxy
114 */
115 /*!
116     \fn void QWebSocket::stateChanged(QAbstractSocket::SocketState state);
117
118     This signal is emitted whenever QWebSocket's state changes.
119     The \a state parameter is the new state.
120
121     \note QAbstractSocket::ConnectedState is emitted after the handshake has
122     with the server has succeeded.
123
124     QAbstractSocket::SocketState is not a registered metatype, so for queued
125     connections, you will have to register it with Q_REGISTER_METATYPE() and
126     qRegisterMetaType().
127
128     \sa state()
129 */
130 /*!
131     \fn void QWebSocket::readChannelFinished()
132
133     This signal is emitted when the input (reading) stream is closed in this device. It is emitted as soon as the closing is detected.
134
135     \sa close()
136 */
137 /*!
138     \fn void QWebSocket::bytesWritten(qint64 bytes)
139
140     This signal is emitted every time a payload of data has been written to the socket.
141     The \a bytes argument is set to the number of bytes that were written in this payload.
142
143     \note This signal has the same meaning both for secure and non-secure websockets.
144     As opposed to QSslSocket, bytesWritten() is only emitted when encrypted data is effectively written (see QSslSocket:encryptedBytesWritten()).
145     \sa close()
146 */
147
148 /*!
149     \fn void QWebSocket::textFrameReceived(QString frame, bool isLastFrame);
150
151     This signal is emitted whenever a text frame is received. The \a frame contains the data and
152     \a isLastFrame indicates whether this is the last frame of the complete message.
153
154     This signal can be used to process large messages frame by frame, instead of waiting for the complete
155     message to arrive.
156
157     \sa binaryFrameReceived()
158 */
159 /*!
160     \fn void QWebSocket::binaryFrameReceived(QByteArray frame, bool isLastFrame);
161
162     This signal is emitted whenever a binary frame is received. The \a frame contains the data and
163     \a isLastFrame indicates whether this is the last frame of the complete message.
164
165     This signal can be used to process large messages frame by frame, instead of waiting for the complete
166     message to arrive.
167
168     \sa textFrameReceived()
169 */
170 /*!
171     \fn void QWebSocket::textMessageReceived(QString message);
172
173     This signal is emitted whenever a text message is received. The \a message contains the received text.
174
175     \sa binaryMessageReceived()
176 */
177 /*!
178     \fn void QWebSocket::binaryMessageReceived(QByteArray message);
179
180     This signal is emitted whenever a binary message is received. The \a message contains the received bytes.
181
182     \sa textMessageReceived()
183 */
184 /*!
185     \fn void QWebSocket::error(QAbstractSocket::SocketError error);
186
187     This signal is emitted after an error occurred. The \a error
188     parameter describes the type of error that occurred.
189
190     QAbstractSocket::SocketError is not a registered metatype, so for queued
191     connections, you will have to register it with Q_DECLARE_METATYPE() and
192     qRegisterMetaType().
193
194     \sa error(), errorString()
195 */
196 /*!
197     \fn void QWebSocket::sslErrors(const QList<QSslError> &errors)
198     QWebSocket emits this signal after the SSL handshake to indicate that one or more errors have occurred
199     while establishing the identity of the peer.
200     The errors are usually an indication that QWebSocket is unable to securely identify the peer.
201     Unless any action is taken, the connection will be dropped after this signal has been emitted.
202     If you want to continue connecting despite the errors that have occurred, you must call QWebSocket::ignoreSslErrors() from inside a slot connected to this signal.
203     If you need to access the error list at a later point, you can call sslErrors() (without arguments).
204
205     \a errors contains one or more errors that prevent QWebSocket from verifying the identity of the peer.
206
207     \note You cannot use Qt::QueuedConnection when connecting to this signal, or calling QWebSocket::ignoreSslErrors() will have no effect.
208 */
209 /*!
210     \fn void QWebSocket::pong(quint64 elapsedTime, QByteArray payload)
211
212     Emitted when a pong message is received in reply to a previous ping.
213     \a elapsedTime contains the roundtrip time in milliseconds and \a payload contains an optional payload that was sent with the ping.
214
215     \sa ping()
216   */
217 #include "qwebsocket.h"
218 #include "qwebsocket_p.h"
219
220 #include <QtCore/QUrl>
221 #include <QtNetwork/QTcpSocket>
222 #include <QtCore/QByteArray>
223 #include <QtNetwork/QHostAddress>
224
225 #include <QtCore/QDebug>
226
227 #include <limits>
228
229 QT_BEGIN_NAMESPACE
230
231 /*!
232  * \brief Creates a new QWebSocket with the given \a origin, the \a version of the protocol to use and \a parent.
233  *
234  * The \a origin of the client is as specified \l {http://tools.ietf.org/html/rfc6454} {RFC 6454}.
235  * (The \a origin is not required for non-web browser clients (see \l {http://tools.ietf.org/html/rfc6455} {RFC 6455})).
236  * \note Currently only V13 (\l {http://tools.ietf.org/html/rfc6455} {RFC 6455}) is supported
237  */
238 QWebSocket::QWebSocket(const QString &origin, QWebSocketProtocol::Version version, QObject *parent) :
239     QObject(parent),
240     d_ptr(new QWebSocketPrivate(origin, version, this, this))
241 {
242 }
243
244 /*!
245  * \brief Destroys the QWebSocket. Closes the socket if it is still open, and releases any used resources.
246  */
247 QWebSocket::~QWebSocket()
248 {
249     delete d_ptr;
250 }
251
252 /*!
253  * \brief Aborts the current socket and resets the socket. Unlike close(), this function immediately closes the socket, discarding any pending data in the write buffer.
254  */
255 void QWebSocket::abort()
256 {
257     Q_D(QWebSocket);
258     d->abort();
259 }
260
261 /*!
262  * Returns the type of error that last occurred
263  * \sa errorString()
264  */
265 QAbstractSocket::SocketError QWebSocket::error() const
266 {
267     Q_D(const QWebSocket);
268     return d->error();
269 }
270
271 //only called by QWebSocketPrivate::upgradeFrom
272 /*!
273   \internal
274  */
275 QWebSocket::QWebSocket(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version, QObject *parent) :
276     QObject(parent),
277     d_ptr(new QWebSocketPrivate(pTcpSocket, version, this, this))
278 {
279 }
280
281 /*!
282  * Returns a human-readable description of the last error that occurred
283  *
284  * \sa error()
285  */
286 QString QWebSocket::errorString() const
287 {
288     Q_D(const QWebSocket);
289     return d->errorString();
290 }
291
292 /*!
293     This function writes as much as possible from the internal write buffer to the underlying network socket, without blocking.
294     If any data was written, this function returns true; otherwise false is returned.
295     Call this function if you need QWebSocket to start sending buffered data immediately.
296     The number of bytes successfully written depends on the operating system.
297     In most cases, you do not need to call this function, because QWebSocket will start sending data automatically once control goes back to the event loop.
298     In the absence of an event loop, call waitForBytesWritten() instead.
299 */
300 bool QWebSocket::flush()
301 {
302     Q_D(QWebSocket);
303     return d->flush();
304 }
305
306 /*!
307     Sends the given \a message over the socket as a text message and returns the number of bytes actually sent.
308     \a message must be '\\0' terminated and is considered to be in UTF-8 encoded format.
309
310     \note When \a message is null or has zero length, zero is returned.
311     \note The maximum size of message, is limited by \l {QString::}{size_type}.
312
313     \sa QString::fromUtf8(), QString::size_type
314  */
315 qint64 QWebSocket::write(const char *message)
316 {
317     Q_D(QWebSocket);
318     return d->write(message);
319 }
320
321 /*!
322     Sends the most \a maxSize bytes of the given \a message over the socket as a text message and returns the number of bytes actually sent.
323     \a message is considered to be in UTF-8 encoded format.
324
325     \note When \a message is null, has zero length or \a maxSize < 0, zero is returned.
326     \note The maximum size of message, is limited by \l {QString::}{size_type}. It the message is larger,
327     it is truncated to the maximum value of \l {QString::}{size_type}.
328
329     \sa QString::fromUtf8(), QString::size_type
330  */
331 qint64 QWebSocket::write(const char *message, qint64 maxSize)
332 {
333     Q_D(QWebSocket);
334     return d->write(message, maxSize);
335 }
336
337 /*!
338     \brief Sends the given \a message over the socket as a text message and returns the number of bytes actually sent.
339  */
340 qint64 QWebSocket::write(const QString &message)
341 {
342     Q_D(QWebSocket);
343     return d->write(message);
344 }
345
346 /*!
347     \brief Sends the given \a data over the socket as a binary message and returns the number of bytes actually sent.
348  */
349 qint64 QWebSocket::write(const QByteArray &data)
350 {
351     Q_D(QWebSocket);
352     return d->write(data);
353 }
354
355 /*!
356     \brief Gracefully closes the socket with the given \a closeCode and \a reason. Any data in the write buffer is flushed before the socket is closed.
357     The \a closeCode is a QWebSocketProtocol::CloseCode indicating the reason to close, and
358     \a reason describes the reason of the closure more in detail
359  */
360 void QWebSocket::close(QWebSocketProtocol::CloseCode closeCode, const QString &reason)
361 {
362     Q_D(QWebSocket);
363     d->close(closeCode, reason);
364 }
365
366 /*!
367     \brief Opens a websocket connection using the given \a url.
368     If \a mask is true, all frames will be masked; this is only necessary for client side sockets; servers should never mask
369     \note A client socket must *always* mask its frames; servers may *never* mask its frames
370  */
371 void QWebSocket::open(const QUrl &url, bool mask)
372 {
373     Q_D(QWebSocket);
374     d->open(url, mask);
375 }
376
377 /*!
378     \brief Pings the server to indicate that the connection is still alive.
379     Additional \a payload can be sent along the ping message.
380
381     The size of the \a payload cannot be bigger than 125. If it is larger, the \a payload is clipped to 125 bytes.
382
383     \sa pong()
384  */
385 void QWebSocket::ping(const QByteArray &payload)
386 {
387     Q_D(QWebSocket);
388     d->ping(payload);
389 }
390
391 #ifndef QT_NO_SSL
392 /*!
393     This slot tells QWebSocket to ignore errors during QWebSocket's
394     handshake phase and continue connecting. If you want to continue
395     with the connection even if errors occur during the handshake
396     phase, then you must call this slot, either from a slot connected
397     to sslErrors(), or before the handshake phase. If you don't call
398     this slot, either in response to errors or before the handshake,
399     the connection will be dropped after the sslErrors() signal has
400     been emitted.
401
402     \warning Be sure to always let the user inspect the errors
403     reported by the sslErrors() signal, and only call this method
404     upon confirmation from the user that proceeding is ok.
405     If there are unexpected errors, the connection should be aborted.
406     Calling this method without inspecting the actual errors will
407     most likely pose a security risk for your application. Use it
408     with great care!
409
410     \sa sslErrors(), QSslSocket::ignoreSslErrors(), QNetworkReply::ignoreSslErrors()
411 */
412 void QWebSocket::ignoreSslErrors()
413 {
414     Q_D(QWebSocket);
415     d->ignoreSslErrors();
416 }
417
418 /*!
419     \overload
420
421     This method tells QWebSocket to ignore the errors given in \a errors.
422
423     Note that you can set the expected certificate in the SSL error:
424     If, for instance, you want to connect to a server that uses
425     a self-signed certificate, consider the following snippet:
426
427     \snippet src_websockets_ssl_qwebsocket.cpp 6
428
429     Multiple calls to this function will replace the list of errors that
430     were passed in previous calls.
431     You can clear the list of errors you want to ignore by calling this
432     function with an empty list.
433
434     \sa sslErrors()
435 */
436 void QWebSocket::ignoreSslErrors(const QList<QSslError> &errors)
437 {
438     Q_D(QWebSocket);
439     d->ignoreSslErrors(errors);
440 }
441
442 /*!
443     Sets the socket's SSL configuration to be the contents of \a sslConfiguration.
444
445     This function sets the local certificate, the ciphers, the private key and the CA certificates to those stored in \a sslConfiguration.
446     It is not possible to set the SSL-state related fields.
447     \sa sslConfiguration()
448  */
449 void QWebSocket::setSslConfiguration(const QSslConfiguration &sslConfiguration)
450 {
451     Q_D(QWebSocket);
452     d->setSslConfiguration(sslConfiguration);
453 }
454
455 /*!
456     Returns the socket's SSL configuration state.
457     The default SSL configuration of a socket is to use the default ciphers, default CA certificates, no local private key or certificate.
458     The SSL configuration also contains fields that can change with time without notice.
459
460     \sa setSslConfiguration()
461  */
462 QSslConfiguration QWebSocket::sslConfiguration() const
463 {
464     Q_D(const QWebSocket);
465     return d->sslConfiguration();
466 }
467
468 #endif  //not QT_NO_SSL
469
470 /*!
471     \brief Returns the version the socket is currently using
472  */
473 QWebSocketProtocol::Version QWebSocket::version() const
474 {
475     Q_D(const QWebSocket);
476     return d->version();
477 }
478
479 /*!
480     \brief Returns the name of the resource currently accessed.
481  */
482 QString QWebSocket::resourceName() const
483 {
484     Q_D(const QWebSocket);
485     return d->resourceName();
486 }
487
488 /*!
489     \brief Returns the url the socket is connected to or will connect to.
490  */
491 QUrl QWebSocket::requestUrl() const
492 {
493     Q_D(const QWebSocket);
494     return d->requestUrl();
495 }
496
497 /*!
498     \brief Returns the current origin
499  */
500 QString QWebSocket::origin() const
501 {
502     Q_D(const QWebSocket);
503     return d->origin();
504 }
505
506 /*!
507     \brief Returns the currently used protocol.
508  */
509 QString QWebSocket::protocol() const
510 {
511     Q_D(const QWebSocket);
512     return d->protocol();
513 }
514
515 /*!
516     \brief Returns the currently used extension.
517  */
518 QString QWebSocket::extension() const
519 {
520     Q_D(const QWebSocket);
521     return d->extension();
522 }
523
524 /*!
525     \brief Returns the code indicating why the socket was closed.
526     \sa QWebSocketProtocol::CloseCode, closeReason()
527  */
528 QWebSocketProtocol::CloseCode QWebSocket::closeCode() const
529 {
530     Q_D(const QWebSocket);
531     return d->closeCode();
532 }
533
534 /*!
535     \brief Returns the reason why the socket was closed.
536     \sa closeCode()
537  */
538 QString QWebSocket::closeReason() const
539 {
540     Q_D(const QWebSocket);
541     return d->closeReason();
542 }
543
544 /*!
545     \brief Returns the current state of the socket
546  */
547 QAbstractSocket::SocketState QWebSocket::state() const
548 {
549     Q_D(const QWebSocket);
550     return d->state();
551 }
552
553 /*!
554     \brief Waits until the socket is connected, up to \a msecs milliseconds. If the connection has been established, this function returns true; otherwise it returns false. In the case where it returns false, you can call error() to determine the cause of the error.
555     The following example waits up to one second for a connection to be established:
556
557     \code
558     socket->open("ws://localhost:1234", false);
559     if (socket->waitForConnected(1000))
560     {
561         qDebug("Connected!");
562     }
563     \endcode
564
565     If \a msecs is -1, this function will not time out.
566     \note This function may wait slightly longer than msecs, depending on the time it takes to complete the host lookup.
567     \note Multiple calls to this functions do not accumulate the time. If the function times out, the connecting process will be aborted.
568
569     \sa connected(), open(), state()
570  */
571 bool QWebSocket::waitForConnected(int msecs)
572 {
573     Q_D(QWebSocket);
574     return d->waitForConnected(msecs);
575 }
576
577 /*!
578   Waits \a msecs for the socket to be disconnected.
579   If the socket was successfully disconnected within time, this method returns true.
580   Otherwise false is returned.
581   When \a msecs is -1, this function will block until the socket is disconnected.
582
583   \sa close(), state()
584 */
585 bool QWebSocket::waitForDisconnected(int msecs)
586 {
587     Q_D(QWebSocket);
588     return d->waitForDisconnected(msecs);
589 }
590
591 /*!
592     Returns the local address
593  */
594 QHostAddress QWebSocket::localAddress() const
595 {
596     Q_D(const QWebSocket);
597     return d->localAddress();
598 }
599
600 /*!
601     Returns the local port
602  */
603 quint16 QWebSocket::localPort() const
604 {
605     Q_D(const QWebSocket);
606     return d->localPort();
607 }
608
609 /*!
610     Returns the pause mode of this socket
611  */
612 QAbstractSocket::PauseModes QWebSocket::pauseMode() const
613 {
614     Q_D(const QWebSocket);
615     return d->pauseMode();
616 }
617
618 /*!
619     Returns the peer address
620  */
621 QHostAddress QWebSocket::peerAddress() const
622 {
623     Q_D(const QWebSocket);
624     return d->peerAddress();
625 }
626
627 /*!
628     Returns the peerName
629  */
630 QString QWebSocket::peerName() const
631 {
632     Q_D(const QWebSocket);
633     return d->peerName();
634 }
635
636 /*!
637     Returns the peerport
638  */
639 quint16 QWebSocket::peerPort() const
640 {
641     Q_D(const QWebSocket);
642     return d->peerPort();
643 }
644
645 #ifndef QT_NO_NETWORKPROXY
646 /*!
647     Returns the currently configured proxy
648  */
649 QNetworkProxy QWebSocket::proxy() const
650 {
651     Q_D(const QWebSocket);
652     return d->proxy();
653 }
654
655 /*!
656     Sets the proxy to \a networkProxy
657  */
658 void QWebSocket::setProxy(const QNetworkProxy &networkProxy)
659 {
660     Q_D(QWebSocket);
661     d->setProxy(networkProxy);
662 }
663 #endif
664
665 /*!
666     Returns the size in bytes of the readbuffer that is used by the socket.
667  */
668 qint64 QWebSocket::readBufferSize() const
669 {
670     Q_D(const QWebSocket);
671     return d->readBufferSize();
672 }
673
674 /*!
675     Continues data transfer on the socket. This method should only be used after the socket
676     has been set to pause upon notifications and a notification has been received.
677     The only notification currently supported is sslErrors().
678     Calling this method if the socket is not paused results in undefined behavior.
679
680     \sa pauseMode(), setPauseMode()
681  */
682 void QWebSocket::resume()
683 {
684     Q_D(QWebSocket);
685     d->resume();
686 }
687
688 /*!
689     Controls whether to pause upon receiving a notification. The \a pauseMode parameter specifies
690     the conditions in which the socket should be paused.
691     The only notification currently supported is sslErrors().
692     If set to PauseOnSslErrors, data transfer on the socket will be paused
693     and needs to be enabled explicitly again by calling resume().
694     By default, this option is set to PauseNever. This option must be called
695     before connecting to the server, otherwise it will result in undefined behavior.
696
697     \sa pauseMode(), resume()
698  */
699 void QWebSocket::setPauseMode(QAbstractSocket::PauseModes pauseMode)
700 {
701     Q_D(QWebSocket);
702     d->setPauseMode(pauseMode);
703 }
704
705 /*!
706     Sets the size of QWebSocket's internal read buffer to be \a size bytes.
707     If the buffer size is limited to a certain size, QWebSocket won't buffer more than this size of data.
708     Exceptionally, a buffer size of 0 means that the read buffer is unlimited and all incoming data is buffered. This is the default.
709     This option is useful if you only read the data at certain points in time (e.g., in a real-time streaming application) or if you want to protect your socket against receiving too much data, which may eventually cause your application to run out of memory.
710     \sa readBufferSize()
711 */
712 void QWebSocket::setReadBufferSize(qint64 size)
713 {
714     Q_D(QWebSocket);
715     d->setReadBufferSize(size);
716 }
717
718 /*!
719     Sets the given \a option to the value described by \a value.
720     \sa socketOption()
721 */
722 void QWebSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
723 {
724     Q_D(QWebSocket);
725     d->setSocketOption(option, value);
726 }
727
728 /*!
729     Returns the value of the option \a option.
730     \sa setSocketOption()
731 */
732 QVariant QWebSocket::socketOption(QAbstractSocket::SocketOption option)
733 {
734     Q_D(QWebSocket);
735     return d->socketOption(option);
736 }
737
738 /*!
739     Returns true if the QWebSocket is valid.
740  */
741 bool QWebSocket::isValid() const
742 {
743     Q_D(const QWebSocket);
744     return d->isValid();
745 }
746
747 QT_END_NAMESPACE