summaryrefslogtreecommitdiff
path: root/src/websockets
diff options
context:
space:
mode:
Diffstat (limited to 'src/websockets')
-rw-r--r--src/websockets/qsslserver_p.cpp87
-rw-r--r--src/websockets/qsslserver_p.h78
-rw-r--r--src/websockets/qwebsocket_p.cpp3
-rw-r--r--src/websockets/qwebsocketframe_p.cpp1
-rw-r--r--src/websockets/qwebsocketserver.cpp52
-rw-r--r--src/websockets/qwebsocketserver.h31
-rw-r--r--src/websockets/qwebsocketserver_p.cpp52
-rw-r--r--src/websockets/qwebsocketserver_p.h22
-rw-r--r--src/websockets/websockets.pro5
9 files changed, 318 insertions, 13 deletions
diff --git a/src/websockets/qsslserver_p.cpp b/src/websockets/qsslserver_p.cpp
new file mode 100644
index 0000000..658243a
--- /dev/null
+++ b/src/websockets/qsslserver_p.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsslserver_p.h"
+
+#include <QtNetwork/QSslSocket>
+#include <QtNetwork/QSslCipher>
+
+QSslServer::QSslServer(QObject *parent) :
+ QTcpServer(parent),
+ m_sslConfiguration(QSslConfiguration::defaultConfiguration())
+{
+}
+
+QSslServer::~QSslServer()
+{
+}
+
+void QSslServer::setSslConfiguration(const QSslConfiguration &sslConfiguration)
+{
+ m_sslConfiguration = sslConfiguration;
+}
+
+QSslConfiguration QSslServer::sslConfiguration() const
+{
+ return m_sslConfiguration;
+}
+
+void QSslServer::incomingConnection(qintptr socket)
+{
+ QSslSocket *pSslSocket = new QSslSocket();
+
+ pSslSocket->setSslConfiguration(m_sslConfiguration);
+
+ if (pSslSocket->setSocketDescriptor(socket))
+ {
+ connect(pSslSocket, SIGNAL(peerVerifyError(QSslError)), this, SIGNAL(peerVerifyError(QSslError)));
+ connect(pSslSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SIGNAL(sslErrors(QList<QSslError>)));
+ connect(pSslSocket, SIGNAL(encrypted()), this, SIGNAL(newEncryptedConnection()));
+
+ addPendingConnection(pSslSocket);
+
+ pSslSocket->startServerEncryption();
+ }
+ else
+ {
+ delete pSslSocket;
+ }
+}
diff --git a/src/websockets/qsslserver_p.h b/src/websockets/qsslserver_p.h
new file mode 100644
index 0000000..789dd58
--- /dev/null
+++ b/src/websockets/qsslserver_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSSLSERVER_P_H
+#define QSSLSERVER_P_H
+
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QSslError>
+#include <QtNetwork/QSslConfiguration>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QSslServer : public QTcpServer
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QSslServer)
+
+public:
+ QSslServer(QObject *parent = Q_NULLPTR);
+ virtual ~QSslServer();
+
+ void setSslConfiguration(const QSslConfiguration &sslConfiguration);
+ QSslConfiguration sslConfiguration() const;
+
+Q_SIGNALS:
+ void sslErrors(const QList<QSslError> &errors);
+ void peerVerifyError(const QSslError &error);
+ void newEncryptedConnection();
+
+protected:
+ virtual void incomingConnection(qintptr socket);
+
+private:
+ QSslConfiguration m_sslConfiguration;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSSLSERVER_P_H
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index 0ae561c..941366f 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -529,7 +529,8 @@ void QWebSocketPrivate::makeConnections(const QTcpSocket *pTcpSocket)
//catch signals
connect(pTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(processStateChanged(QAbstractSocket::SocketState)));
- connect(pTcpSocket, SIGNAL(readyRead()), this, SLOT(processData()));
+ //!!!important to use a QueuedConnection here; with QTcpSocket there is no problem, but with QSslSocket the processing hangs
+ connect(pTcpSocket, SIGNAL(readyRead()), this, SLOT(processData()), Qt::QueuedConnection);
connect(&m_dataProcessor, SIGNAL(textFrameReceived(QString,bool)), q, SIGNAL(textFrameReceived(QString,bool)));
connect(&m_dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool)), q, SIGNAL(binaryFrameReceived(QByteArray,bool)));
diff --git a/src/websockets/qwebsocketframe_p.cpp b/src/websockets/qwebsocketframe_p.cpp
index afb0ece..4fab472 100644
--- a/src/websockets/qwebsocketframe_p.cpp
+++ b/src/websockets/qwebsocketframe_p.cpp
@@ -410,7 +410,6 @@ QWebSocketFrame QWebSocketFrame::readFrame(QIODevice *pIoDevice)
{
if (pIoDevice->bytesAvailable() >= 4)
{
- //TODO: big endian conversion?
bytesRead = pIoDevice->read(reinterpret_cast<char *>(&frame.m_mask), sizeof(frame.m_mask));
if (bytesRead == -1)
{
diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp
index f89e79b..176de35 100644
--- a/src/websockets/qwebsocketserver.cpp
+++ b/src/websockets/qwebsocketserver.cpp
@@ -130,17 +130,25 @@
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QNetworkProxy>
+#ifndef QT_NO_SSL
+#include <QtNetwork/QSslConfiguration>
+#endif
+
QT_BEGIN_NAMESPACE
/*!
Constructs a new WebSocketServer with the given \a serverName.
The \a serverName will be used in the http handshake phase to identify the server.
+
\a parent is passed to the QObject constructor.
*/
-QWebSocketServer::QWebSocketServer(const QString &serverName, QObject *parent) :
+QWebSocketServer::QWebSocketServer(const QString &serverName, SecureMode secureMode, QObject *parent) :
QObject(parent),
- d_ptr(new QWebSocketServerPrivate(serverName, this, this))
+ d_ptr(new QWebSocketServerPrivate(serverName,
+ (secureMode == SECURE_MODE) ? QWebSocketServerPrivate::SECURE_MODE : QWebSocketServerPrivate::NON_SECURE_MODE,
+ this,
+ this))
{
}
@@ -277,6 +285,34 @@ void QWebSocketServer::setProxy(const QNetworkProxy &networkProxy)
d->setProxy(networkProxy);
}
#endif
+
+#ifndef QT_NO_SSL
+/*!
+ Sets the SSL configuration for the websocket server to \a sslConfiguration.
+ This method has no effect if QWebSocketServer runs in non-secure mode (QWebSocketServer::NON_SECURE_MODE).
+
+ \sa sslConfiguration(), SecureMode
+ */
+void QWebSocketServer::setSslConfiguration(const QSslConfiguration &sslConfiguration)
+{
+ Q_D(QWebSocketServer);
+ d->setSslConfiguration(sslConfiguration);
+}
+
+/*!
+ Returns the SSL configuration used by the websocket server.
+ If the server is not running in secure mode (QWebSocketServer::SECURE_MODE),
+ this method returns QSslConfiguration::defaultConfiguration().
+
+ \sa sslConfiguration(), SecureMode, QSslConfiguration::defaultConfiguration()
+ */
+QSslConfiguration QWebSocketServer::sslConfiguration() const
+{
+ Q_D(const QWebSocketServer);
+ return d->sslConfiguration();
+}
+#endif
+
/*!
Resumes accepting new connections.
\sa pauseAccepting()
@@ -319,6 +355,18 @@ QHostAddress QWebSocketServer::serverAddress() const
}
/*!
+ Returns the mode the server is running in.
+
+ \sa QWebSocketServer(), SecureMode
+ */
+QWebSocketServer::SecureMode QWebSocketServer::secureMode() const
+{
+ Q_D(const QWebSocketServer);
+ return (d->secureMode() == QWebSocketServerPrivate::SECURE_MODE) ?
+ QWebSocketServer::SECURE_MODE : QWebSocketServer::NON_SECURE_MODE;
+}
+
+/*!
Returns an error code for the last error that occurred.
\sa errorString()
*/
diff --git a/src/websockets/qwebsocketserver.h b/src/websockets/qwebsocketserver.h
index a925fda..c616c0b 100644
--- a/src/websockets/qwebsocketserver.h
+++ b/src/websockets/qwebsocketserver.h
@@ -42,12 +42,17 @@
#ifndef QWEBSOCKETSERVER_H
#define QWEBSOCKETSERVER_H
+#include "QtWebSockets/qwebsockets_global.h"
+#include "QtWebSockets/qwebsocketprotocol.h"
+
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtNetwork/QHostAddress>
-#include "QtWebSockets/qwebsockets_global.h"
-#include "QtWebSockets/qwebsocketprotocol.h"
+#ifndef QT_NO_SSL
+#include <QtNetwork/QSslConfiguration>
+#include <QtNetwork/QSslError>
+#endif
QT_BEGIN_NAMESPACE
@@ -61,8 +66,17 @@ class Q_WEBSOCKETS_EXPORT QWebSocketServer : public QObject
Q_DISABLE_COPY(QWebSocketServer)
Q_DECLARE_PRIVATE(QWebSocketServer)
+ Q_ENUMS(SecureMode)
+
public:
- explicit QWebSocketServer(const QString &serverName, QObject *parent = Q_NULLPTR);
+ enum SecureMode {
+#ifndef QT_NO_SSL
+ SECURE_MODE,
+#endif
+ NON_SECURE_MODE
+ };
+
+ explicit QWebSocketServer(const QString &serverName, SecureMode secureMode, QObject *parent = Q_NULLPTR);
virtual ~QWebSocketServer();
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
@@ -76,6 +90,8 @@ public:
quint16 serverPort() const;
QHostAddress serverAddress() const;
+ SecureMode secureMode() const;
+
bool setSocketDescriptor(int socketDescriptor);
int socketDescriptor() const;
@@ -96,6 +112,10 @@ public:
void setProxy(const QNetworkProxy &networkProxy);
QNetworkProxy proxy() const;
#endif
+#ifndef QT_NO_SSL
+ void setSslConfiguration(const QSslConfiguration &sslConfiguration);
+ QSslConfiguration sslConfiguration() const;
+#endif
QList<QWebSocketProtocol::Version> supportedVersions() const;
QList<QString> supportedProtocols() const;
@@ -103,8 +123,13 @@ public:
Q_SIGNALS:
void acceptError(QAbstractSocket::SocketError socketError);
+ //TODO: should use a delegate iso of a synchronous signal
void originAuthenticationRequired(QWebSocketCorsAuthenticator *pAuthenticator);
void newConnection();
+#ifndef QT_NO_SSL
+ void peerVerifyError(const QSslError &error);
+ void sslErrors(const QList<QSslError> &errors);
+#endif
private:
QWebSocketServerPrivate * const d_ptr;
diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp
index 10f328a..3772eee 100644
--- a/src/websockets/qwebsocketserver_p.cpp
+++ b/src/websockets/qwebsocketserver_p.cpp
@@ -41,6 +41,9 @@
#include "qwebsocketserver.h"
#include "qwebsocketserver_p.h"
+#ifndef QT_NO_SSL
+#include "qsslserver_p.h"
+#endif
#include "qwebsocketprotocol.h"
#include "qwebsockethandshakerequest_p.h"
#include "qwebsockethandshakeresponse_p.h"
@@ -57,17 +60,32 @@ QT_BEGIN_NAMESPACE
/*!
\internal
*/
-QWebSocketServerPrivate::QWebSocketServerPrivate(const QString &serverName, QWebSocketServer * const pWebSocketServer, QObject *parent) :
+QWebSocketServerPrivate::QWebSocketServerPrivate(const QString &serverName, QWebSocketServerPrivate::SecureMode secureMode,
+ QWebSocketServer * const pWebSocketServer, QObject *parent) :
QObject(parent),
q_ptr(pWebSocketServer),
m_pTcpServer(Q_NULLPTR),
m_serverName(serverName),
+ m_secureMode(secureMode),
m_pendingConnections()
{
Q_ASSERT(pWebSocketServer);
- m_pTcpServer = new QTcpServer(this);
+ if (m_secureMode == NON_SECURE_MODE)
+ {
+ m_pTcpServer = new QTcpServer(this);
+ connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
+ }
+ else
+ {
+#ifndef QT_NO_SSL
+ QSslServer *pSslServer = new QSslServer(this);
+ m_pTcpServer = pSslServer;
+ connect(pSslServer, SIGNAL(newEncryptedConnection()), this, SLOT(onNewConnection()));
+ connect(pSslServer, SIGNAL(peerVerifyError(QSslError)), q_ptr, SIGNAL(peerVerifyError(QSslError)));
+ connect(pSslServer, SIGNAL(sslErrors(QList<QSslError>)), q_ptr, SIGNAL(sslErrors(QList<QSslError>)));
+#endif
+ }
connect(m_pTcpServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), q_ptr, SIGNAL(acceptError(QAbstractSocket::SocketError)));
- connect(m_pTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
/*!
@@ -290,6 +308,34 @@ QString QWebSocketServerPrivate::serverName() const
}
/*!
+ \internal
+ */
+QWebSocketServerPrivate::SecureMode QWebSocketServerPrivate::secureMode() const
+{
+ return m_secureMode;
+}
+
+void QWebSocketServerPrivate::setSslConfiguration(const QSslConfiguration &sslConfiguration)
+{
+ if (m_secureMode == SECURE_MODE)
+ {
+ qobject_cast<QSslServer *>(m_pTcpServer)->setSslConfiguration(sslConfiguration);
+ }
+}
+
+QSslConfiguration QWebSocketServerPrivate::sslConfiguration() const
+{
+ if (m_secureMode == SECURE_MODE)
+ {
+ return qobject_cast<QSslServer *>(m_pTcpServer)->sslConfiguration();
+ }
+ else
+ {
+ return QSslConfiguration::defaultConfiguration();
+ }
+}
+
+/*!
\internal
*/
void QWebSocketServerPrivate::onNewConnection()
diff --git a/src/websockets/qwebsocketserver_p.h b/src/websockets/qwebsocketserver_p.h
index 94491f7..5e089d7 100644
--- a/src/websockets/qwebsocketserver_p.h
+++ b/src/websockets/qwebsocketserver_p.h
@@ -58,6 +58,11 @@
#include <QtNetwork/QHostAddress>
#include "qwebsocket.h"
+#ifndef QT_NO_SSL
+#include <QtNetwork/QSslConfiguration>
+#include <QtNetwork/QSslError>
+#endif
+
QT_BEGIN_NAMESPACE
class QTcpServer;
@@ -70,7 +75,13 @@ class QWebSocketServerPrivate : public QObject
Q_DECLARE_PUBLIC(QWebSocketServer)
public:
- explicit QWebSocketServerPrivate(const QString &serverName, QWebSocketServer * const pWebSocketServer, QObject *parent = Q_NULLPTR);
+ enum SecureMode
+ {
+ SECURE_MODE = true,
+ NON_SECURE_MODE
+ };
+
+ explicit QWebSocketServerPrivate(const QString &serverName, SecureMode secureMode, QWebSocketServer * const pWebSocketServer, QObject *parent = Q_NULLPTR);
virtual ~QWebSocketServerPrivate();
void close();
@@ -101,8 +112,12 @@ public:
void setServerName(const QString &serverName);
QString serverName() const;
-Q_SIGNALS:
- void newConnection();
+ SecureMode secureMode() const;
+
+#ifndef QT_NO_SSL
+ void setSslConfiguration(const QSslConfiguration &sslConfiguration);
+ QSslConfiguration sslConfiguration() const;
+#endif
private Q_SLOTS:
void onNewConnection();
@@ -114,6 +129,7 @@ private:
QTcpServer *m_pTcpServer;
QString m_serverName;
+ SecureMode m_secureMode;
QQueue<QWebSocket *> m_pendingConnections;
void addPendingConnection(QWebSocket *pWebSocket);
diff --git a/src/websockets/websockets.pro b/src/websockets/websockets.pro
index f17fcbd..4b67717 100644
--- a/src/websockets/websockets.pro
+++ b/src/websockets/websockets.pro
@@ -40,6 +40,11 @@ SOURCES += \
$$PWD/qwebsocketcorsauthenticator.cpp \
$$PWD/qwebsocketframe_p.cpp
+contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
+ SOURCES += $$PWD/qsslserver_p.cpp
+ PRIVATE_HEADERS += $$PWD/qsslserver_p.h
+}
+
HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
load(qt_module)