summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergio Ahumada <sahumada@blackberry.com>2014-03-13 14:50:03 +0100
committerSergio Ahumada <sahumada@blackberry.com>2014-03-13 14:50:05 +0100
commit974fd5f831cf9abfbd900c49ab6c21fb04ef62da (patch)
tree235666b5d896d5c86db5325215720425b5508ffa /src
parente677361e300a7747a500c3879217727a53aae245 (diff)
parentd4ac9f51f6d18a05016e3d61c06eace27501f589 (diff)
downloadqtwebsockets-974fd5f831cf9abfbd900c49ab6c21fb04ef62da.tar.gz
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I0ee590f834200c488498315e66acf7cd046d43ad
Diffstat (limited to 'src')
-rw-r--r--src/websockets/doc/qtwebsockets.qdocconf4
-rw-r--r--src/websockets/doc/src/index.qdoc9
-rw-r--r--src/websockets/doc/src/qtwebsockets-module.qdoc6
-rw-r--r--src/websockets/qdefaultmaskgenerator_p.cpp41
-rw-r--r--src/websockets/qmaskgenerator.cpp8
-rw-r--r--src/websockets/qsslserver.cpp41
-rw-r--r--src/websockets/qsslserver_p.h2
-rw-r--r--src/websockets/qwebsocket.cpp4
-rw-r--r--src/websockets/qwebsocket_p.cpp2
-rw-r--r--src/websockets/qwebsockethandshakeresponse.cpp2
-rw-r--r--src/websockets/qwebsocketserver.cpp7
-rw-r--r--src/websockets/qwebsocketserver_p.cpp18
12 files changed, 131 insertions, 13 deletions
diff --git a/src/websockets/doc/qtwebsockets.qdocconf b/src/websockets/doc/qtwebsockets.qdocconf
index 434c9f2..7822edc 100644
--- a/src/websockets/doc/qtwebsockets.qdocconf
+++ b/src/websockets/doc/qtwebsockets.qdocconf
@@ -40,11 +40,11 @@ tagfile = ../../../doc/qtwebsockets/
depends += qtcore qtnetwork qtdoc
-headerdirs += ..
+headerdirs += .. \
../../imports
sourcedirs += .. \
- src
+ src \
../../imports
diff --git a/src/websockets/doc/src/index.qdoc b/src/websockets/doc/src/index.qdoc
index f85380b..2961ef3 100644
--- a/src/websockets/doc/src/index.qdoc
+++ b/src/websockets/doc/src/index.qdoc
@@ -50,10 +50,15 @@
QT += websockets
\endcode
- \section1 Related information
+ \section1 Reference documentation
\list
\li \l{Qt WebSockets C++ Classes}{C++ Classes}
- \li \l{Qt WebSockets Examples}{Examples}
\li \l{Qt WebSockets QML Types}{QML Types}
\endlist
+
+ \section1 Examples
+
+ The module provides the following examples as a guide to using
+ the API.
+ \l{Qt WebSockets Examples}{Examples}
*/
diff --git a/src/websockets/doc/src/qtwebsockets-module.qdoc b/src/websockets/doc/src/qtwebsockets-module.qdoc
index c4dea41..02d31d1 100644
--- a/src/websockets/doc/src/qtwebsockets-module.qdoc
+++ b/src/websockets/doc/src/qtwebsockets-module.qdoc
@@ -29,6 +29,7 @@
\title Qt WebSockets C++ Classes
\ingroup modules
\qtvariable websockets
+ \since 5.3
\brief List of C++ classes that provide WebSockets communication.
To use these classes in your application, use the following include
@@ -52,4 +53,9 @@
\brief List of QML types that provide WebSockets communication.
\annotatedlist websockets-qml
+
+ The QML types are accessed by using:
+ \code
+ import QtWebSockets 1.0
+ \endcode
*/
diff --git a/src/websockets/qdefaultmaskgenerator_p.cpp b/src/websockets/qdefaultmaskgenerator_p.cpp
index 814e04d..da166ac 100644
--- a/src/websockets/qdefaultmaskgenerator_p.cpp
+++ b/src/websockets/qdefaultmaskgenerator_p.cpp
@@ -38,6 +38,26 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+/*!
+ \class QDefaultMaskGenerator
+
+ \inmodule QtWebSockets
+
+ \brief The QDefaultMaskGenerator class provides the default mask generator for QtWebSockets.
+
+ The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455}
+ requires that all communication from client to server must be masked. This is to prevent
+ malicious scripts to attack bad behaving proxies.
+ For more information about the importance of good masking,
+ see \l {http://w2spconf.com/2011/papers/websocket.pdf}.
+ The default mask generator uses the cryptographically insecure qrand() function.
+ The best measure against attacks mentioned in the document above,
+ is to use QWebSocket over a secure connection (\e wss://).
+ In general, always be careful to not have 3rd party script access to
+ a QWebSocket in your application.
+
+ \internal
+*/
#include "qdefaultmaskgenerator_p.h"
#include <QDateTime>
@@ -45,21 +65,42 @@
QT_BEGIN_NAMESPACE
+/*!
+ Constructs a new QDefaultMaskGenerator with the given \a parent.
+
+ \internal
+*/
QDefaultMaskGenerator::QDefaultMaskGenerator(QObject *parent) :
QMaskGenerator(parent)
{
}
+/*!
+ Destroys the QDefaultMaskGenerator object.
+
+ \internal
+*/
QDefaultMaskGenerator::~QDefaultMaskGenerator()
{
}
+/*!
+ Seeds the QDefaultMaskGenerator using qsrand().
+ When seed() is not called, no seed is used at all.
+
+ \internal
+*/
bool QDefaultMaskGenerator::seed()
{
qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
return true;
}
+/*!
+ Generates a new random mask using the insecure qrand() method.
+
+ \internal
+*/
quint32 QDefaultMaskGenerator::nextMask()
{
return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
diff --git a/src/websockets/qmaskgenerator.cpp b/src/websockets/qmaskgenerator.cpp
index aa78f77..04f5e1e 100644
--- a/src/websockets/qmaskgenerator.cpp
+++ b/src/websockets/qmaskgenerator.cpp
@@ -41,7 +41,10 @@
/*!
\class QMaskGenerator
- The QMaskGenerator class provides an abstract base for custom 32-bit mask generators.
+
+ \inmodule QtWebSockets
+
+ \brief The QMaskGenerator class provides an abstract base for custom 32-bit mask generators.
The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455}
requires that all communication from client to server must be masked. This is to prevent
@@ -61,6 +64,7 @@
Initializes the QMaskGenerator by seeding the randomizer.
When seed() is not called, it depends on the specific implementation of a subclass if
a default seed is used or no seed is used at all.
+ Returns \e true if seeding succeeds, otherwise false.
*/
/*!
@@ -75,7 +79,7 @@
QT_BEGIN_NAMESPACE
/*!
- Creates a new QMaskGenerator object.
+ Creates a new QMaskGenerator object with the given optional QObject \a parent.
*/
QMaskGenerator::QMaskGenerator(QObject *parent) :
QObject(parent)
diff --git a/src/websockets/qsslserver.cpp b/src/websockets/qsslserver.cpp
index d1add19..e5faded 100644
--- a/src/websockets/qsslserver.cpp
+++ b/src/websockets/qsslserver.cpp
@@ -39,6 +39,16 @@
**
****************************************************************************/
+/*!
+ \class QSslServer
+
+ \inmodule QtWebSockets
+
+ \brief Implements a secure TCP server over SSL.
+
+ \internal
+*/
+
#include "qsslserver_p.h"
#include <QtNetwork/QSslSocket>
@@ -46,26 +56,57 @@
QT_BEGIN_NAMESPACE
+/*!
+ Constructs a new QSslServer with the given \a parent.
+
+ \internal
+*/
QSslServer::QSslServer(QObject *parent) :
QTcpServer(parent),
m_sslConfiguration(QSslConfiguration::defaultConfiguration())
{
}
+/*!
+ Destroys the QSslServer.
+
+ All open connections are closed.
+
+ \internal
+*/
QSslServer::~QSslServer()
{
}
+/*!
+ Sets the \a sslConfiguration to use.
+
+ \sa QSslSocket::setSslConfiguration()
+
+ \internal
+*/
void QSslServer::setSslConfiguration(const QSslConfiguration &sslConfiguration)
{
m_sslConfiguration = sslConfiguration;
}
+/*!
+ Returns the current ssl configuration.
+
+ \internal
+*/
QSslConfiguration QSslServer::sslConfiguration() const
{
return m_sslConfiguration;
}
+/*!
+ Called when a new connection is established.
+
+ Converts \a socket to a QSslSocket.
+
+ \internal
+*/
void QSslServer::incomingConnection(qintptr socket)
{
QSslSocket *pSslSocket = new QSslSocket();
diff --git a/src/websockets/qsslserver_p.h b/src/websockets/qsslserver_p.h
index 12da3c5..12b9369 100644
--- a/src/websockets/qsslserver_p.h
+++ b/src/websockets/qsslserver_p.h
@@ -55,7 +55,7 @@ class QSslServer : public QTcpServer
Q_DISABLE_COPY(QSslServer)
public:
- QSslServer(QObject *parent = Q_NULLPTR);
+ explicit QSslServer(QObject *parent = Q_NULLPTR);
virtual ~QSslServer();
void setSslConfiguration(const QSslConfiguration &sslConfiguration);
diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index 707d459..85b45c0 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -60,6 +60,10 @@
QWebSocket only supports version 13 of the WebSocket protocol, as outlined in
\l {http://tools.ietf.org/html/rfc6455}{RFC 6455}.
+ \note Some proxies do not understand certain HTTP headers used during a web socket handshake.
+ In that case, non-secure web socket connections fail. The best way to mitigate against
+ this problem is to use web sockets over a secure connection.
+
\warning To generate masks, this implementation of WebSockets uses the cryptographically
insecure qrand() function.
For more information about the importance of good masking,
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index be589db..c51ba38 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -92,7 +92,7 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::
QObjectPrivate(),
q_ptr(pWebSocket),
m_pSocket(),
- m_errorString(QWebSocket::tr("Unknown error")),
+ m_errorString(),
m_version(version),
m_resourceName(),
m_requestUrl(),
diff --git a/src/websockets/qwebsockethandshakeresponse.cpp b/src/websockets/qwebsockethandshakeresponse.cpp
index d244000..aa9a881 100644
--- a/src/websockets/qwebsockethandshakeresponse.cpp
+++ b/src/websockets/qwebsockethandshakeresponse.cpp
@@ -207,7 +207,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse(
if (Q_UNLIKELY(!m_canUpgrade)) {
response << QStringLiteral("HTTP/1.1 400 Bad Request");
QStringList versions;
- Q_FOREACH (QWebSocketProtocol::Version version, supportedVersions)
+ Q_FOREACH (const QWebSocketProtocol::Version &version, supportedVersions)
versions << QString::number(static_cast<int>(version));
response << QStringLiteral("Sec-WebSocket-Version: ")
% versions.join(QStringLiteral(", "));
diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp
index 0645947..884f422 100644
--- a/src/websockets/qwebsocketserver.cpp
+++ b/src/websockets/qwebsocketserver.cpp
@@ -70,6 +70,13 @@
\l {http://tools.ietf.org/html/rfc6455#page-39} {extensions} and
\l {http://tools.ietf.org/html/rfc6455#page-12} {subprotocols}.
+ \note When working with self-signed certificates, FireFox currently has a
+ \l {https://bugzilla.mozilla.org/show_bug.cgi?id=594502} {bug} that prevents it to
+ connect to a secure websocket server. To work around this problem, first browse to the
+ secure websocket server using https. FireFox will indicate that the certificate is invalid.
+ From here on, the certificate can be added to the exceptions. After this, the secure websockets
+ connection should work.
+
QWebSocketServer only supports version 13 of the WebSocket protocol, as outlined in RFC 6455.
\sa echoserver.html
diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp
index a43e75a..f349dc2 100644
--- a/src/websockets/qwebsocketserver_p.cpp
+++ b/src/websockets/qwebsocketserver_p.cpp
@@ -94,7 +94,8 @@ void QWebSocketServerPrivate::init()
m_pTcpServer = pSslServer;
if (Q_LIKELY(m_pTcpServer)) {
QObjectPrivate::connect(pSslServer, &QSslServer::newEncryptedConnection,
- this, &QWebSocketServerPrivate::onNewConnection);
+ this, &QWebSocketServerPrivate::onNewConnection,
+ Qt::QueuedConnection);
QObject::connect(pSslServer, &QSslServer::peerVerifyError,
q_ptr, &QWebSocketServer::peerVerifyError);
QObject::connect(pSslServer, &QSslServer::sslErrors,
@@ -414,13 +415,22 @@ void QWebSocketServerPrivate::handshakeReceived()
qWarning() << QWebSocketServer::tr("Sender is not a QTcpSocket. This is a Qt bug!!!");
return;
}
+ //When using Google Chrome the handshake in received in two parts.
+ //Therefore, the readyRead signal is emitted twice.
+ //This is a guard against the BEAST attack.
+ //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html
+ //For Safari, the handshake is delivered at once
+ //FIXME: For FireFox, the readyRead signal is never emitted
+ //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502)
+ if (!pTcpSocket->canReadLine()) {
+ return;
+ }
+ disconnect(pTcpSocket, &QTcpSocket::readyRead,
+ this, &QWebSocketServerPrivate::handshakeReceived);
Q_Q(QWebSocketServer);
bool success = false;
bool isSecure = false;
- disconnect(pTcpSocket, &QTcpSocket::readyRead,
- this, &QWebSocketServerPrivate::handshakeReceived);
-
if (m_pendingConnections.length() >= maxPendingConnections()) {
pTcpSocket->close();
pTcpSocket->deleteLater();