summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Pattyn <pattyn.kurt@gmail.com>2013-11-01 13:12:28 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-01 13:13:35 +0100
commitd26e2ce1594af6e9088b176ccb31c4033e367839 (patch)
treea083044aa5ef67fddf3a57f67f4f1b5630468909
parent3501d4e9c315af97f0d7878d1af7f4300a815ea3 (diff)
downloadqtwebsockets-d26e2ce1594af6e9088b176ccb31c4033e367839.tar.gz
Add functionality to ignore ssl errors
Change-Id: I81248b9af104c0b3d37c9cfcef250a102f4b1d32 Reviewed-by: Kurt Pattyn <pattyn.kurt@gmail.com>
-rw-r--r--.qmake.conf2
-rw-r--r--examples/echoclient/echoclient.h2
-rw-r--r--src/websockets/qwebsocket.cpp55
-rw-r--r--src/websockets/qwebsocket.h7
-rw-r--r--src/websockets/qwebsocket_p.cpp41
-rw-r--r--src/websockets/qwebsocket_p.h5
-rw-r--r--src/websockets/qwebsocketprotocol.h1
-rw-r--r--tests/autobahn/compliance/tst_compliance.cpp8
8 files changed, 112 insertions, 9 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 4fb101b..33b0cc8 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
CONFIG += qt_example_installs
-MODULE_VERSION = 5.1.1
+MODULE_VERSION = 5.2.0
diff --git a/examples/echoclient/echoclient.h b/examples/echoclient/echoclient.h
index 7d3033e..35578d2 100644
--- a/examples/echoclient/echoclient.h
+++ b/examples/echoclient/echoclient.h
@@ -2,7 +2,7 @@
#define ECHOCLIENT_H
#include <QObject>
-#include "qwebsocket.h"
+#include <QtWebSockets/QWebSocket>
class EchoClient : public QObject
{
diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index b1fc57c..46c7776 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -114,7 +114,7 @@ not been filled in with new information when the signal returns.
The \a bytes argument is set to the number of bytes that were written in this payload.
\note This signal has the same meaning both for secure and non-secure websockets.
- As opposed to QSslSocket, bytesWritten() is only emitted when encrypted data is effectively written (\sa {{QSslSocket:}}{{encryptedBytesWritten}}).
+ As opposed to QSslSocket, bytesWritten() is only emitted when encrypted data is effectively written (\sa QSslSocket:encryptedBytesWritten()).
\sa close()
*/
@@ -339,6 +339,59 @@ void QWebSocket::ping(const QByteArray &payload)
d->ping(payload);
}
+#ifndef QT_NO_SSL
+/*!
+ This slot tells QWebSocket to ignore errors during QWebSocket's
+ handshake phase and continue connecting. If you want to continue
+ with the connection even if errors occur during the handshake
+ phase, then you must call this slot, either from a slot connected
+ to sslErrors(), or before the handshake phase. If you don't call
+ this slot, either in response to errors or before the handshake,
+ the connection will be dropped after the sslErrors() signal has
+ been emitted.
+
+ \warning Be sure to always let the user inspect the errors
+ reported by the sslErrors() signal, and only call this method
+ upon confirmation from the user that proceeding is ok.
+ If there are unexpected errors, the connection should be aborted.
+ Calling this method without inspecting the actual errors will
+ most likely pose a security risk for your application. Use it
+ with great care!
+
+ \sa sslErrors(), QSslSocket::ignoreSslErrors(), QNetworkReply::ignoreSslErrors()
+*/
+void QWebSocket::ignoreSslErrors()
+{
+ Q_D(QWebSocket);
+ d->ignoreSslErrors();
+}
+
+/*!
+ \overload
+
+ This method tells QWebSocket to ignore the errors given in \a errors.
+
+ Note that you can set the expected certificate in the SSL error:
+ If, for instance, you want to connect to a server that uses
+ a self-signed certificate, consider the following snippet:
+
+ \snippet src_websockets_ssl_qwebsocket 6
+
+ Multiple calls to this function will replace the list of errors that
+ were passed in previous calls.
+ You can clear the list of errors you want to ignore by calling this
+ function with an empty list.
+
+ \sa sslErrors()
+*/
+void QWebSocket::ignoreSslErrors(const QList<QSslError> &errors)
+{
+ Q_D(QWebSocket);
+ d->ignoreSslErrors(errors);
+}
+
+#endif //not QT_NO_SSL
+
/*!
\brief Returns the version the socket is currently using
*/
diff --git a/src/websockets/qwebsocket.h b/src/websockets/qwebsocket.h
index fbc3b36..a49e992 100644
--- a/src/websockets/qwebsocket.h
+++ b/src/websockets/qwebsocket.h
@@ -96,6 +96,9 @@ public Q_SLOTS:
void close(QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CC_NORMAL, const QString &reason = QString());
void open(const QUrl &url, bool mask = true);
void ping(const QByteArray &payload = QByteArray());
+#ifndef QT_NO_SSL
+ void ignoreSslErrors();
+#endif
Q_SIGNALS:
void aboutToClose();
@@ -114,6 +117,10 @@ Q_SIGNALS:
void pong(quint64 elapsedTime, QByteArray payload);
void bytesWritten(qint64 bytes);
+#ifndef QT_NO_SSL
+ void sslErrors(const QList<QSslError> &errors);
+#endif
+
private:
QWebSocket(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version, QObject *parent = Q_NULLPTR);
QWebSocketPrivate * const d_ptr;
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index e47f4e6..f8e407a 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -48,6 +48,11 @@ const quint64 FRAME_SIZE_IN_BYTES = 512 * 512 * 2; //maximum size of a frame whe
QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::Version version, QWebSocket *pWebSocket, QObject *parent) :
QObject(parent),
q_ptr(pWebSocket),
+#ifndef QT_NO_SSL
+ m_sslConfiguration(),
+ m_ignoredSslErrors(),
+ m_ignoreSslErrors(false),
+#endif
m_pSocket(Q_NULLPTR),
m_errorString(),
m_version(version),
@@ -75,6 +80,11 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::
QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version, QWebSocket *pWebSocket, QObject *parent) :
QObject(parent),
q_ptr(pWebSocket),
+#ifndef QT_NO_SSL
+ m_sslConfiguration(), //socket is already open, so we don't need to set the ssl configuration anymore
+ m_ignoredSslErrors(), //socket is already open, so we don't need to set the ignored errors anymore
+ m_ignoreSslErrors(false),
+#endif
m_pSocket(pTcpSocket),
m_errorString(pTcpSocket->errorString()),
m_version(version),
@@ -209,6 +219,14 @@ void QWebSocketPrivate::ignoreSslErrors(const QList<QSslError> &errors)
m_ignoredSslErrors = errors;
}
+/*!
+ * \internal
+ */
+void QWebSocketPrivate::ignoreSslErrors()
+{
+ m_ignoreSslErrors = true;
+}
+
#endif
/*!
@@ -301,10 +319,10 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask)
{
if (!QSslSocket::supportsSsl())
{
- qWarning() << tr("SSL Sockets are not supported on this platform.");
- setErrorString(tr("SSL Sockets are not supported on this platform."));
+ const QString message = tr("SSL Sockets are not supported on this platform.");
+ qWarning() << message;
+ setErrorString(message);
emit q->error(QAbstractSocket::UnsupportedSocketOperationError);
- return;
}
else
{
@@ -316,12 +334,20 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask)
setSocketState(QAbstractSocket::ConnectingState);
sslSocket->setSslConfiguration(m_sslConfiguration);
- sslSocket->ignoreSslErrors(m_ignoredSslErrors);
+ if (m_ignoreSslErrors)
+ {
+ sslSocket->ignoreSslErrors();
+ }
+ else
+ {
+ sslSocket->ignoreSslErrors(m_ignoredSslErrors);
+ }
sslSocket->connectToHostEncrypted(url.host(), url.port(443));
}
}
else
#endif
+ if (url.scheme() == QStringLiteral("ws"))
{
m_pSocket = new QTcpSocket(this);
@@ -330,6 +356,13 @@ void QWebSocketPrivate::open(const QUrl &url, bool mask)
setSocketState(QAbstractSocket::ConnectingState);
m_pSocket->connectToHost(url.host(), url.port(80));
}
+ else
+ {
+ const QString message = tr("Unsupported websockets scheme: %1").arg(url.scheme());
+ qWarning() << message;
+ setErrorString(message);
+ emit q->error(QAbstractSocket::UnsupportedSocketOperationError);
+ }
}
/*!
diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h
index 90543e3..345b63a 100644
--- a/src/websockets/qwebsocket_p.h
+++ b/src/websockets/qwebsocket_p.h
@@ -113,6 +113,10 @@ public Q_SLOTS:
void open(const QUrl &url, bool mask);
void ping(const QByteArray &payload);
+#ifndef QT_NO_SSL
+ void ignoreSslErrors();
+#endif
+
private Q_SLOTS:
void processData();
void processPing(QByteArray data);
@@ -126,6 +130,7 @@ private:
#ifndef QT_NO_SSL
QSslConfiguration m_sslConfiguration;
QList<QSslError> m_ignoredSslErrors;
+ bool m_ignoreSslErrors;
#endif
QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol::Version version, QWebSocket *pWebSocket, QObject *parent = Q_NULLPTR);
diff --git a/src/websockets/qwebsocketprotocol.h b/src/websockets/qwebsocketprotocol.h
index ca2d09f..4d4dd6a 100644
--- a/src/websockets/qwebsocketprotocol.h
+++ b/src/websockets/qwebsocketprotocol.h
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#define QWEBSOCKETPROTOCOL_H
#include <qglobal.h>
+#include "qwebsockets_global.h"
QT_BEGIN_NAMESPACE
diff --git a/tests/autobahn/compliance/tst_compliance.cpp b/tests/autobahn/compliance/tst_compliance.cpp
index c1c9318..e1c4fad 100644
--- a/tests/autobahn/compliance/tst_compliance.cpp
+++ b/tests/autobahn/compliance/tst_compliance.cpp
@@ -2,8 +2,9 @@
#include <QtTest/qtestcase.h>
#include <QSignalSpy>
#include <QHostInfo>
+#include <QSslError>
#include <QDebug>
-#include "qwebsocket.h"
+#include <QWebSocket>
class tst_ComplianceTest : public QObject
{
@@ -30,7 +31,7 @@ private:
};
tst_ComplianceTest::tst_ComplianceTest() :
- m_url("ws://localhost:9001")
+ m_url("wss://localhost:9001")
{
}
@@ -56,7 +57,9 @@ void tst_ComplianceTest::runTestCase(int nbr, int total)
{
return;
}
+
QWebSocket *pWebSocket = new QWebSocket;
+ pWebSocket->ignoreSslErrors();
QSignalSpy spy(pWebSocket, SIGNAL(disconnected()));
//next for every case, connect to url
@@ -93,6 +96,7 @@ void tst_ComplianceTest::autobahnTest()
{
//connect to autobahn server at url ws://ipaddress:port/getCaseCount
QWebSocket *pWebSocket = new QWebSocket;
+ pWebSocket->ignoreSslErrors();
QUrl url = m_url;
int numberOfTestCases = 0;
QSignalSpy spy(pWebSocket, SIGNAL(disconnected()));