summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKurt Pattyn <pattyn.kurt@gmail.com>2013-08-31 20:43:37 +0200
committerKurt Pattyn <pattyn.kurt@gmail.com>2013-08-31 20:43:37 +0200
commit197a715ee19abb4574a30b4c3687b82ebf6fd969 (patch)
tree52f4565764e622a104fc2369292fc67de52da8c6 /src
parentf552e33fcce55919f8f025143ba89ad26721cbd5 (diff)
downloadqtwebsockets-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.cpp132
-rw-r--r--src/qcorsauthenticator.h48
-rw-r--r--src/qcorsauthenticator_p.h29
-rw-r--r--src/qwebsockets.pri7
-rw-r--r--src/qwebsocketserver.cpp28
-rw-r--r--src/qwebsocketserver.h5
-rw-r--r--src/qwebsocketserver_p.cpp6
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());