There was no '?' between path and query. Bug detected by someone on the internet.
[contrib/qtwebsockets.git] / src / qwebsocket.cpp
1 /*
2 QWebSockets implements the WebSocket protocol as defined in RFC 6455.
3 Copyright (C) 2013 Kurt Pattyn (pattyn.kurt@gmail.com)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20 /*!
21     \class QWebSocket
22
23     \inmodule QWebSockets
24     \brief Implements a TCP socket that talks the websocket protocol.
25
26     WebSockets is a web technology providing full-duplex communications channels over a single TCP connection.
27     The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011 (see http://tools.ietf.org/html/rfc6455).
28     It can both be used in a client application and server application.
29
30     This class was modeled after QAbstractSocket.
31
32     \sa QAbstractSocket, QTcpSocket
33
34     \sa echoclient.html
35 */
36
37 /*!
38     \page echoclient.html example
39     \title QWebSocket client example
40     \brief A sample websocket client that sends a message and displays the message that it receives back.
41
42     \section1 Description
43     The EchoClient example implements a web socket client that sends a message to a websocket server and dumps the answer that it gets back.
44     This example should ideally be used with the EchoServer example.
45     \section1 Code
46     We start by connecting to the `connected()` signal.
47     \snippet echoclient.cpp constructor
48     After the connection, we open the socket to the given \a url.
49
50     \snippet echoclient.cpp onConnected
51     When the client is connected successfully, we connect to the `onTextMessageReceived()` signal, and send out "Hello, world!".
52     If connected with the EchoServer, we will receive the same message back.
53
54     \snippet echoclient.cpp onTextMessageReceived
55     Whenever a message is received, we write it out.
56 */
57
58 /*!
59   \fn void QWebSocket::connected()
60   \brief Emitted when a connection is successfully established.
61   \sa open(), disconnected()
62 */
63 /*!
64   \fn void QWebSocket::disconnected()
65   \brief Emitted when the socket is disconnected.
66   \sa close(), connected()
67 */
68 /*!
69     \fn void QWebSocket::aboutToClose()
70
71     This signal is emitted when the socket is about to close.
72     Connect this signal if you have operations that need to be performed before the socket closes
73     (e.g., if you have data in a separate buffer that needs to be written to the device).
74
75     \sa close()
76  */
77 /*!
78 \fn void QWebSocket::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
79
80 This signal can be emitted when a \a proxy that requires
81 authentication is used. The \a authenticator object can then be
82 filled in with the required details to allow authentication and
83 continue the connection.
84
85 \note It is not possible to use a QueuedConnection to connect to
86 this signal, as the connection will fail if the authenticator has
87 not been filled in with new information when the signal returns.
88
89 \sa QAuthenticator, QNetworkProxy
90 */
91 /*!
92     \fn void QWebSocket::stateChanged(QAbstractSocket::SocketState state);
93
94     This signal is emitted whenever QWebSocket's state changes.
95     The \a state parameter is the new state.
96
97     QAbstractSocket::SocketState is not a registered metatype, so for queued
98     connections, you will have to register it with Q_REGISTER_METATYPE() and
99     qRegisterMetaType().
100
101     \sa state()
102 */
103 /*!
104     \fn void QWebSocket::readChannelFinished()
105
106     This signal is emitted when the input (reading) stream is closed in this device. It is emitted as soon as the closing is detected.
107
108     \sa close()
109 */
110
111 /*!
112     \fn void QWebSocket::textFrameReceived(QString frame, bool isLastFrame);
113
114     This signal is emitted whenever a text frame is received. The \a frame contains the data and
115     \a isLastFrame indicates whether this is the last frame of the complete message.
116
117     This signal can be used to process large messages frame by frame, instead of waiting for the complete
118     message to arrive.
119
120     \sa binaryFrameReceived()
121 */
122 /*!
123     \fn void QWebSocket::binaryFrameReceived(QByteArray frame, bool isLastFrame);
124
125     This signal is emitted whenever a binary frame is received. The \a frame contains the data and
126     \a isLastFrame indicates whether this is the last frame of the complete message.
127
128     This signal can be used to process large messages frame by frame, instead of waiting for the complete
129     message to arrive.
130
131     \sa textFrameReceived()
132 */
133 /*!
134     \fn void QWebSocket::textMessageReceived(QString message);
135
136     This signal is emitted whenever a text message is received. The \a message contains the received text.
137
138     \sa binaryMessageReceived()
139 */
140 /*!
141     \fn void QWebSocket::binaryMessageReceived(QByteArray message);
142
143     This signal is emitted whenever a binary message is received. The \a message contains the received bytes.
144
145     \sa textMessageReceived()
146 */
147 /*!
148     \fn void QWebSocket::error(QAbstractSocket::SocketError error);
149
150     This signal is emitted after an error occurred. The \a error
151     parameter describes the type of error that occurred.
152
153     QAbstractSocket::SocketError is not a registered metatype, so for queued
154     connections, you will have to register it with Q_DECLARE_METATYPE() and
155     qRegisterMetaType().
156
157     \sa error(), errorString()
158 */
159 /*!
160     \fn void QWebSocket::pong(quint64 elapsedTime, QByteArray payload)
161
162     Emitted when a pong message is received in reply to a previous ping.
163     \a elapsedTime contains the roundtrip time in milliseconds and \a payload contains an optional payload that was sent with the ping.
164
165     \sa ping()
166   */
167 #include "qwebsocket.h"
168 #include "qwebsocket_p.h"
169 #include <QUrl>
170 #include <QTcpSocket>
171 #include <QByteArray>
172 #include <QHostAddress>
173
174 #include <QDebug>
175
176 #include <limits>
177
178 QT_BEGIN_NAMESPACE
179
180 const quint64 FRAME_SIZE_IN_BYTES = 512 * 512 * 2;      //maximum size of a frame when sending a message
181
182 /*!
183  * \brief Creates a new QWebSocket with the given \a origin, the \a version of the protocol to use and \a parent.
184  *
185  * The \a origin of the client is as specified in http://tools.ietf.org/html/rfc6454.
186  * (The \a origin is not required for non-web browser clients (see RFC 6455)).
187  * \note Currently only V13 (RFC 6455) is supported
188  */
189 QWebSocket::QWebSocket(const QString &origin, QWebSocketProtocol::Version version, QObject *parent) :
190     QObject(parent),
191     d_ptr(new QWebSocketPrivate(origin, version, this, this))
192 {
193 }
194
195 /*!
196  * \brief Destroys the QWebSocket. Closes the socket if it is still open, and releases any used resources.
197  */
198 QWebSocket::~QWebSocket()
199 {
200     delete d_ptr;
201     //d_ptr = 0;
202 }
203
204 /*!
205  * \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.
206  */
207 void QWebSocket::abort()
208 {
209     Q_D(QWebSocket);
210     d->abort();
211 }
212
213 /*!
214  * Returns the type of error that last occurred
215  * \sa errorString()
216  */
217 QAbstractSocket::SocketError QWebSocket::error() const
218 {
219     Q_D(const QWebSocket);
220     return d->error();
221 }
222
223 //only called by QWebSocketPrivate::upgradeFrom
224 /*!
225   \internal
226  */
227 QWebSocket::QWebSocket(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version, QObject *parent) :
228     QObject(parent),
229     d_ptr(new QWebSocketPrivate(pTcpSocket, version, this, this))
230 {
231 }
232
233 /*!
234  * Returns a human-readable description of the last error that occurred
235  *
236  * \sa error()
237  */
238 QString QWebSocket::errorString() const
239 {
240     Q_D(const QWebSocket);
241     return d->errorString();
242 }
243
244 /*!
245     This function writes as much as possible from the internal write buffer to the underlying network socket, without blocking.
246     If any data was written, this function returns true; otherwise false is returned.
247     Call this function if you need QWebSocket to start sending buffered data immediately.
248     The number of bytes successfully written depends on the operating system.
249     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.
250     In the absence of an event loop, call waitForBytesWritten() instead.
251 */
252 bool QWebSocket::flush()
253 {
254     Q_D(QWebSocket);
255     return d->flush();
256 }
257
258 /*!
259     Sends the given \a message over the socket as a text message and returns the number of bytes actually sent.
260     \a message must be '\\0' terminated.
261  */
262 qint64 QWebSocket::write(const char *message)
263 {
264     Q_D(QWebSocket);
265     return d->write(message);
266 }
267
268 /*!
269     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.
270  */
271 qint64 QWebSocket::write(const char *message, qint64 maxSize)
272 {
273     Q_D(QWebSocket);
274     return d->write(message, maxSize);
275 }
276
277 /*!
278     \brief Sends the given \a message over the socket as a text message and returns the number of bytes actually sent.
279  */
280 qint64 QWebSocket::write(const QString &message)
281 {
282     Q_D(QWebSocket);
283     return d->write(message);
284 }
285
286 /*!
287     \brief Sends the given \a data over the socket as a binary message and returns the number of bytes actually sent.
288  */
289 qint64 QWebSocket::write(const QByteArray &data)
290 {
291     Q_D(QWebSocket);
292     return d->write(data);
293 }
294
295 /*!
296     \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.
297     The \a closeCode is a QWebSocketProtocol::CloseCode indicating the reason to close, and
298     \a reason describes the reason of the closure more in detail
299  */
300 void QWebSocket::close(QWebSocketProtocol::CloseCode closeCode, const QString &reason)
301 {
302     Q_D(QWebSocket);
303     d->close(closeCode, reason);
304 }
305
306 /*!
307     \brief Opens a websocket connection using the given \a url.
308     If \a mask is true, all frames will be masked; this is only necessary for client side sockets; servers should never mask
309     \note A client socket must *always* mask its frames; servers may *never* mask its frames
310  */
311 void QWebSocket::open(const QUrl &url, bool mask)
312 {
313     Q_D(QWebSocket);
314     d->open(url, mask);
315 }
316
317 /*!
318     \brief Pings the server to indicate that the connection is still alive.
319     Additional \a payload can be sent along the ping message.
320
321     The size of the \a payload cannot be bigger than 125. If it is larger, the \a payload is clipped to 125 bytes.
322
323     \sa pong()
324  */
325 void QWebSocket::ping(const QByteArray &payload)
326 {
327     Q_D(QWebSocket);
328     if (payload.length() > 125)
329     {
330         payload.left(125);
331     }
332     d->ping(payload);
333 }
334
335 /*!
336     \brief Returns the version the socket is currently using
337  */
338 QWebSocketProtocol::Version QWebSocket::version() const
339 {
340     Q_D(const QWebSocket);
341     return d->version();
342 }
343
344 /*!
345     \brief Returns the name of the resource currently accessed.
346  */
347 QString QWebSocket::resourceName() const
348 {
349     Q_D(const QWebSocket);
350     return d->resourceName();
351 }
352
353 /*!
354     \brief Returns the url the socket is connected to or will connect to.
355  */
356 QUrl QWebSocket::requestUrl() const
357 {
358     Q_D(const QWebSocket);
359     return d->requestUrl();
360 }
361
362 /*!
363     \brief Returns the current origin
364  */
365 QString QWebSocket::origin() const
366 {
367     Q_D(const QWebSocket);
368     return d->origin();
369 }
370
371 /*!
372     \brief Returns the currently used protocol.
373  */
374 QString QWebSocket::protocol() const
375 {
376     Q_D(const QWebSocket);
377     return d->protocol();
378 }
379
380 /*!
381     \brief Returns the currently used extension.
382  */
383 QString QWebSocket::extension() const
384 {
385     Q_D(const QWebSocket);
386     return d->extension();
387 }
388
389 /*!
390     \brief Returns the current state of the socket
391  */
392 QAbstractSocket::SocketState QWebSocket::state() const
393 {
394     Q_D(const QWebSocket);
395     return d->state();
396 }
397
398 /*!
399     \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.
400     The following example waits up to one second for a connection to be established:
401
402     ~~~{.cpp}
403     socket->open("ws://localhost:1234", false);
404     if (socket->waitForConnected(1000))
405     {
406         qDebug("Connected!");
407     }
408     ~~~
409
410     If \a msecs is -1, this function will not time out.
411     @note This function may wait slightly longer than msecs, depending on the time it takes to complete the host lookup.
412     @note Multiple calls to this functions do not accumulate the time. If the function times out, the connecting process will be aborted.
413
414     \sa connected(), open(), state()
415  */
416 bool QWebSocket::waitForConnected(int msecs)
417 {
418     Q_D(QWebSocket);
419     return d->waitForConnected(msecs);
420 }
421
422 /*!
423   Waits \a msecs for the socket to be disconnected.
424   If the socket was successfully disconnected within time, this method returns true.
425   Otherwise false is returned.
426   When \a msecs is -1, this function will block until the socket is disconnected.
427
428   \sa close(), state()
429 */
430 bool QWebSocket::waitForDisconnected(int msecs)
431 {
432     Q_D(QWebSocket);
433     return d->waitForDisconnected(msecs);
434 }
435
436 /*!
437     Returns the local address
438  */
439 QHostAddress QWebSocket::localAddress() const
440 {
441     Q_D(const QWebSocket);
442     return d->localAddress();
443 }
444
445 /*!
446     Returns the local port
447  */
448 quint16 QWebSocket::localPort() const
449 {
450     Q_D(const QWebSocket);
451     return d->localPort();
452 }
453
454 /*!
455     Returns the pause mode of this socket
456  */
457 QAbstractSocket::PauseModes QWebSocket::pauseMode() const
458 {
459     Q_D(const QWebSocket);
460     return d->pauseMode();
461 }
462
463 /*!
464     Returns the peer address
465  */
466 QHostAddress QWebSocket::peerAddress() const
467 {
468     Q_D(const QWebSocket);
469     return d->peerAddress();
470 }
471
472 /*!
473     Returns the peerName
474  */
475 QString QWebSocket::peerName() const
476 {
477     Q_D(const QWebSocket);
478     return d->peerName();
479 }
480
481 /*!
482     Returns the peerport
483  */
484 quint16 QWebSocket::peerPort() const
485 {
486     Q_D(const QWebSocket);
487     return d->peerPort();
488 }
489
490 #ifndef QT_NO_NETWORKPROXY
491 /*!
492     Returns the currently configured proxy
493  */
494 QNetworkProxy QWebSocket::proxy() const
495 {
496     Q_D(const QWebSocket);
497     return d->proxy();
498 }
499
500 /*!
501     Sets the proxy to \a networkProxy
502  */
503 void QWebSocket::setProxy(const QNetworkProxy &networkProxy)
504 {
505     Q_D(QWebSocket);
506     d->setProxy(networkProxy);
507 }
508 #endif
509
510 /*!
511     Returns the size in bytes of the readbuffer that is used by the socket.
512  */
513 qint64 QWebSocket::readBufferSize() const
514 {
515     Q_D(const QWebSocket);
516     return d->readBufferSize();
517 }
518
519 /*!
520     Continues data transfer on the socket. This method should only be used after the socket
521     has been set to pause upon notifications and a notification has been received.
522     The only notification currently supported is sslErrors().
523     Calling this method if the socket is not paused results in undefined behavior.
524
525     \sa pauseMode(), setPauseMode()
526  */
527 void QWebSocket::resume()
528 {
529     Q_D(QWebSocket);
530     d->resume();
531 }
532
533 /*!
534     Controls whether to pause upon receiving a notification. The \a pauseMode parameter specifies
535     the conditions in which the socket should be paused.
536     The only notification currently supported is sslErrors().
537     If set to PauseOnSslErrors, data transfer on the socket will be paused
538     and needs to be enabled explicitly again by calling resume().
539     By default, this option is set to PauseNever. This option must be called
540     before connecting to the server, otherwise it will result in undefined behavior.
541
542     \sa pauseMode(), resume()
543  */
544 void QWebSocket::setPauseMode(QAbstractSocket::PauseModes pauseMode)
545 {
546     Q_D(QWebSocket);
547     d->setPauseMode(pauseMode);
548 }
549
550 /*!
551     Sets the size of QWebSocket's internal read buffer to be \a size bytes.
552     If the buffer size is limited to a certain size, QWebSocket won't buffer more than this size of data.
553     Exceptionally, a buffer size of 0 means that the read buffer is unlimited and all incoming data is buffered. This is the default.
554     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.
555     \sa readBufferSize()
556 */
557 void QWebSocket::setReadBufferSize(qint64 size)
558 {
559     Q_D(QWebSocket);
560     d->setReadBufferSize(size);
561 }
562
563 /*!
564     Sets the given \a option to the value described by \a value.
565     \sa socketOption()
566 */
567 void QWebSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
568 {
569     Q_D(QWebSocket);
570     d->setSocketOption(option, value);
571 }
572
573 /*!
574     Returns the value of the option \a option.
575     \sa setSocketOption()
576 */
577 QVariant QWebSocket::socketOption(QAbstractSocket::SocketOption option)
578 {
579     Q_D(QWebSocket);
580     return d->socketOption(option);
581 }
582
583 /*!
584     Returns true if the QWebSocket is valid.
585  */
586 bool QWebSocket::isValid() const
587 {
588     Q_D(const QWebSocket);
589     return d->isValid();
590 }
591
592 QT_END_NAMESPACE