diff options
author | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-11-06 20:00:39 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-06 20:02:37 +0100 |
commit | 91f93d2781e494d7835385aa501667d71ae231e7 (patch) | |
tree | 5eb0055dd628942073c7291249e93542f84f899c /src/websockets | |
parent | 529b9a7cc85f63966c8ed6150ea18286b7459b1e (diff) | |
download | qtwebsockets-91f93d2781e494d7835385aa501667d71ae231e7.tar.gz |
Add sslEchoClient and sslEchoServer examples
Add license headers
Change-Id: Ied74cb3db6ceed6c3f361e4afac860a7a3fb7676
Reviewed-by: Kurt Pattyn <pattyn.kurt@gmail.com>
Diffstat (limited to 'src/websockets')
-rw-r--r-- | src/websockets/qsslserver_p.cpp | 87 | ||||
-rw-r--r-- | src/websockets/qsslserver_p.h | 78 | ||||
-rw-r--r-- | src/websockets/qwebsocket_p.cpp | 3 | ||||
-rw-r--r-- | src/websockets/qwebsocketframe_p.cpp | 1 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver.cpp | 52 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver.h | 31 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver_p.cpp | 52 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver_p.h | 22 | ||||
-rw-r--r-- | src/websockets/websockets.pro | 5 |
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) |