diff options
author | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-08-31 20:43:37 +0200 |
---|---|---|
committer | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-08-31 20:43:37 +0200 |
commit | 197a715ee19abb4574a30b4c3687b82ebf6fd969 (patch) | |
tree | 52f4565764e622a104fc2369292fc67de52da8c6 /src | |
parent | f552e33fcce55919f8f025143ba89ad26721cbd5 (diff) | |
download | qtwebsockets-197a715ee19abb4574a30b4c3687b82ebf6fd969.tar.gz |
Changed the way origins are checked. Instead of a virtual method, we now use a QCorsAuthenticator object and the signal originAuthenticationRequired(). This is modelled after the way QNetworkAccessManager handles authentication.
By using a signal iso of virtual method, applications must not subclass QWebSocketServer anymore to add origin checks.
Diffstat (limited to 'src')
-rw-r--r-- | src/qcorsauthenticator.cpp | 132 | ||||
-rw-r--r-- | src/qcorsauthenticator.h | 48 | ||||
-rw-r--r-- | src/qcorsauthenticator_p.h | 29 | ||||
-rw-r--r-- | src/qwebsockets.pri | 7 | ||||
-rw-r--r-- | src/qwebsocketserver.cpp | 28 | ||||
-rw-r--r-- | src/qwebsocketserver.h | 5 | ||||
-rw-r--r-- | src/qwebsocketserver_p.cpp | 6 |
7 files changed, 233 insertions, 22 deletions
diff --git a/src/qcorsauthenticator.cpp b/src/qcorsauthenticator.cpp new file mode 100644 index 0000000..5c7e581 --- /dev/null +++ b/src/qcorsauthenticator.cpp @@ -0,0 +1,132 @@ +/* +QWebSockets implements the WebSocket protocol as defined in RFC 6455. +Copyright (C) 2013 Kurt Pattyn (pattyn.kurt@gmail.com) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/*! + \class QCorsAuthenticator + + \inmodule QWebSockets + \brief The QCorsAuthenticator class provides an authenticator object for Cross Origin Requests (CORS). + + The QCorsAuthenticator class is used in the \l{QWebSocketServer::}{originAuthenticationRequired()} signal. + The class provides a way to pass back the required information to the QWebSocketServer. + It provides applications with fine-grained control over which origin URLs are allowed and which aren't. + By default, every origin is accepted. + To get fine grained control, an application connects the \l{QWebSocketServer::}{originAuthenticationRequired()} signal to + a slot. When the origin (QCorsAuthenticator::origin()) is accepted, it calls QCorsAuthenticator::setAllowed(true) + + \note Checking on the origin does not make much sense when the server is accessed + via a non-browser client, as that client can set whatever origin header it likes. + In case of a browser client, the server SHOULD check the validity of the origin. + \sa http://tools.ietf.org/html/rfc6455#section-10 + + \sa QWebSocketServer +*/ + +#include "qcorsauthenticator.h" +#include "qcorsauthenticator_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \internal + */ +QCorsAuthenticatorPrivate::QCorsAuthenticatorPrivate(const QString &origin, bool allowed) : + m_origin(origin), + m_isAllowed(allowed) +{} + +/*! + \internal + */ +QCorsAuthenticatorPrivate::~QCorsAuthenticatorPrivate() +{} + +/*! + Constructs a new QCorsAuthencator object with the given \a origin. + \note By default, allowed() returns true. This means that per default every origin is accepted. + */ +QCorsAuthenticator::QCorsAuthenticator(const QString &origin) : + d_ptr(new QCorsAuthenticatorPrivate(origin, true)) //all origins are per default allowed +{ +} + +/*! + Destructs the object + */ +QCorsAuthenticator::~QCorsAuthenticator() +{ + if (d_ptr) + { + delete d_ptr; + } +} + +/*! + Constructs a coy of \a other + */ +QCorsAuthenticator::QCorsAuthenticator(const QCorsAuthenticator &other) : + d_ptr(new QCorsAuthenticatorPrivate(other.d_ptr->m_origin, other.d_ptr->m_isAllowed)) +{ +} + +/*! + Assigns \a other to this authenticator object + */ +QCorsAuthenticator &QCorsAuthenticator::operator =(const QCorsAuthenticator &other) +{ + Q_D(QCorsAuthenticator); + if (this != &other) + { + d->m_origin = other.d_ptr->m_origin; + d->m_isAllowed = other.d_ptr->m_isAllowed; + } + return *this; +} + +/*! + Returns the origin this autenticator is handling about. + */ +QString QCorsAuthenticator::origin() const +{ + Q_D(const QCorsAuthenticator); + return d->m_origin; +} + +/*! + Allows or disallows the origin. Setting \a allowed to true, will accept the connection request for the given origin. + Setting \a allowed to false, will reject the connection request. + + \note By default, all origins are accepted. + */ +void QCorsAuthenticator::setAllowed(bool allowed) +{ + Q_D(QCorsAuthenticator); + d->m_isAllowed = allowed; +} + +/*! + Returns true if the origin is allowed, otherwise returns false. + + \note By default, all origins are accepted. + */ +bool QCorsAuthenticator::allowed() const +{ + Q_D(const QCorsAuthenticator); + return d->m_isAllowed; +} diff --git a/src/qcorsauthenticator.h b/src/qcorsauthenticator.h new file mode 100644 index 0000000..acf997a --- /dev/null +++ b/src/qcorsauthenticator.h @@ -0,0 +1,48 @@ +/* +QWebSockets implements the WebSocket protocol as defined in RFC 6455. +Copyright (C) 2013 Kurt Pattyn (pattyn.kurt@gmail.com) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef QCORSAUTHENTICATOR_H +#define QCORSAUTHENTICATOR_H + +#include "qwebsocketsglobal.h" + +QT_BEGIN_NAMESPACE + +class QCorsAuthenticatorPrivate; + +class Q_WEBSOCKETS_EXPORT QCorsAuthenticator +{ +public: + QCorsAuthenticator(const QString &origin); + ~QCorsAuthenticator(); + QCorsAuthenticator(const QCorsAuthenticator &other); + + QCorsAuthenticator &operator =(const QCorsAuthenticator &other); + + QString origin() const; + + void setAllowed(bool allowed); + bool allowed() const; + +private: + Q_DECLARE_PRIVATE(QCorsAuthenticator) + + QCorsAuthenticatorPrivate * const d_ptr; +}; + +#endif // QCORSAUTHENTICATOR_H diff --git a/src/qcorsauthenticator_p.h b/src/qcorsauthenticator_p.h new file mode 100644 index 0000000..ee218dc --- /dev/null +++ b/src/qcorsauthenticator_p.h @@ -0,0 +1,29 @@ +#ifndef QCORSAUTHENTICATOR_P_H +#define QCORSAUTHENTICATOR_P_H + +#include <qglobal.h> //for QT_BEGIN_NAMESPACE +#include <QString> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// +QT_BEGIN_NAMESPACE + +class QCorsAuthenticatorPrivate +{ +public: + QCorsAuthenticatorPrivate(const QString &origin, bool allowed); + ~QCorsAuthenticatorPrivate(); + + QString m_origin; + bool m_isAllowed; +}; + +#endif // QCORSAUTHENTICATOR_P_H diff --git a/src/qwebsockets.pri b/src/qwebsockets.pri index ec2ebd8..c701c93 100644 --- a/src/qwebsockets.pri +++ b/src/qwebsockets.pri @@ -8,7 +8,8 @@ SOURCES += \ $$PWD/qwebsocketprotocol.cpp \ $$PWD/handshakerequest_p.cpp \ $$PWD/handshakeresponse_p.cpp \ - $$PWD/dataprocessor_p.cpp + $$PWD/dataprocessor_p.cpp \ + $$PWD/qcorsauthenticator.cpp HEADERS += \ $$PWD/qwebsocket.h \ @@ -19,7 +20,9 @@ HEADERS += \ $$PWD/handshakerequest_p.h \ $$PWD/handshakeresponse_p.h \ $$PWD/dataprocessor_p.h \ - $$PWD/qwebsocketsglobal.h + $$PWD/qwebsocketsglobal.h \ + $$PWD/qcorsauthenticator.h \ + qcorsauthenticator_p.h INCLUDEPATH += $$PWD DEPENDPATH += $$PWD diff --git a/src/qwebsocketserver.cpp b/src/qwebsocketserver.cpp index 219a979..03c0ec2 100644 --- a/src/qwebsocketserver.cpp +++ b/src/qwebsocketserver.cpp @@ -87,6 +87,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA \sa hasPendingConnections(), nextPendingConnection() */ +/*! + \fn void QWebSocketServer::originAuthenticationRequired(QCorsAuthenticator *authenticator) + This signal is emitted when a new connection is requested. + The slot connected to this signal should indicate whether the origin (which can be determined by the origin() call) + is allowed in the \a authenticator object (by issuing \l{QCorsAuthenticator::}{setAllowed()}) + + If no slot is connected to this signal, all origins will be accepted by default. + + \note It is not possible to use a QueuedConnection to connect to + this signal, as the connection will always succeed. +*/ + #include <QTcpServer> #include <QTcpSocket> #include <QNetworkProxy> @@ -392,20 +404,4 @@ QList<QString> QWebSocketServer::supportedExtensions() const return d->supportedExtensions(); } -/*! - This method checks if the given \a origin is allowed; it returns true when the \a origin is allowed, otherwise false. - It is supposed to be overriden by a subclass to filter out unwanted origins. - By default, every origin is accepted. - - \note Checking on the origin does not make much sense when the server is accessed - via a non-browser client, as that client can set whatever origin header it likes - In case of a browser client, the server SHOULD check the validity of the origin. - \sa http://tools.ietf.org/html/rfc6455#section-10 -*/ -bool QWebSocketServer::isOriginAllowed(const QString &origin) const -{ - Q_UNUSED(origin) - return true; -} - QT_END_NAMESPACE diff --git a/src/qwebsocketserver.h b/src/qwebsocketserver.h index 91f4693..6579b53 100644 --- a/src/qwebsocketserver.h +++ b/src/qwebsocketserver.h @@ -30,6 +30,7 @@ QT_BEGIN_NAMESPACE class QWebSocketServerPrivate; class QWebSocket; +class QCorsAuthenticator; class Q_WEBSOCKETS_EXPORT QWebSocketServer : public QObject { @@ -75,11 +76,9 @@ public: QList<QString> supportedProtocols() const; QList<QString> supportedExtensions() const; -protected: - virtual bool isOriginAllowed(const QString &origin) const; - Q_SIGNALS: void acceptError(QAbstractSocket::SocketError socketError); + void originAuthenticationRequired(QCorsAuthenticator *pAuthenticator); void newConnection(); private: diff --git a/src/qwebsocketserver_p.cpp b/src/qwebsocketserver_p.cpp index 4dc08a0..8e4bc7b 100644 --- a/src/qwebsocketserver_p.cpp +++ b/src/qwebsocketserver_p.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "handshakeresponse_p.h" #include "qwebsocket.h" #include "qwebsocket_p.h" +#include "qcorsauthenticator.h" QT_BEGIN_NAMESPACE @@ -301,9 +302,12 @@ void QWebSocketServerPrivate::handshakeReceived() QTextStream textStream(pTcpSocket); textStream >> request; + QCorsAuthenticator corsAuthenticator(request.getOrigin()); + Q_EMIT q->originAuthenticationRequired(&corsAuthenticator); + HandshakeResponse response(request, m_serverName, - q->isOriginAllowed(request.getOrigin()), + corsAuthenticator.allowed(), supportedVersions(), supportedProtocols(), supportedExtensions()); |