diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2013-02-20 15:01:35 +0100 |
---|---|---|
committer | Pierre Rossi <pierre.rossi@gmail.com> | 2013-11-01 13:57:49 +0100 |
commit | b1d0a375185925506e893d3b32cf19a941a73141 (patch) | |
tree | 834a670e5989c9791cb00968803025bc63757cc3 | |
parent | 211f8ac57b6718dd36691ac34326e9aa405664b6 (diff) | |
download | qtwebchannel-b1d0a375185925506e893d3b32cf19a941a73141.tar.gz |
Validate the QWebChannel secret and use the QWebChannel protocol.
Change-Id: Idafda1326de072f9fa1853cb54cb0de459186bb1
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
-rw-r--r-- | src/qwebchannel.cpp | 48 | ||||
-rw-r--r-- | src/qwebsocketserver.cpp | 9 | ||||
-rw-r--r-- | src/qwebsocketserver.h | 7 | ||||
-rw-r--r-- | src/webchannel.js | 2 |
4 files changed, 40 insertions, 26 deletions
diff --git a/src/qwebchannel.cpp b/src/qwebchannel.cpp index 7ae766e..2a78624 100644 --- a/src/qwebchannel.cpp +++ b/src/qwebchannel.cpp @@ -47,31 +47,25 @@ #include "qwebsocketserver.h" -class QWebChannelPrivate : public QObject +class QWebChannelPrivate : public QWebSocketServer { Q_OBJECT public: - QWebSocketServer m_server; - QString m_secret; + QByteArray m_secret; bool m_useSecret; QString m_baseUrl; bool m_starting; QWebChannelPrivate(QObject* parent) - : QObject(parent) + : QWebSocketServer(parent) , m_useSecret(true) , m_starting(false) { - connect(&m_server, SIGNAL(error(QAbstractSocket::SocketError)), + connect(this, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketError())); } - virtual ~QWebChannelPrivate() - { - m_server.close(); - } - void initLater() { if (m_starting) @@ -84,41 +78,55 @@ signals: void failed(const QString& reason); void initialized(); +protected: + virtual bool isValid(const HeaderData& connection); + private slots: void init(); void socketError(); }; +bool QWebChannelPrivate::isValid(const HeaderData& connection) +{ + if (!QWebSocketServer::isValid(connection)) { + return false; + } + return connection.protocol == QByteArrayLiteral("QWebChannel") + && connection.path == m_secret; +} + void QWebChannelPrivate::init() { - m_server.close(); + close(); m_starting = false; if (m_useSecret) { - m_secret = QUuid::createUuid().toString(); - m_secret = m_secret.mid(1, m_secret.size() - 2); + m_secret = QUuid::createUuid().toByteArray(); + // replace { by / + m_secret[0] = '/'; + // chop of trailing } + m_secret.chop(1); } - if (!m_server.listen(QHostAddress::LocalHost)) { - emit failed(m_server.errorString()); + if (!listen(QHostAddress::LocalHost)) { + emit failed(errorString()); return; } - m_baseUrl = QString("localhost:%1/%2").arg(m_server.port()).arg(m_secret); - qDebug() << m_baseUrl; + m_baseUrl = QString("localhost:%1%2").arg(port()).arg(QString::fromLatin1(m_secret)); emit initialized(); } void QWebChannelPrivate::socketError() { - emit failed(m_server.errorString()); + emit failed(errorString()); } QWebChannel::QWebChannel(QObject *parent) : QObject(parent) , d(new QWebChannelPrivate(this)) { - connect(&d->m_server, SIGNAL(textDataReceived(QString)), + connect(d, SIGNAL(textDataReceived(QString)), SIGNAL(rawMessageReceived(QString))); connect(d, SIGNAL(failed(QString)), SIGNAL(failed(QString))); @@ -157,7 +165,7 @@ void QWebChannel::onInitialized() void QWebChannel::sendRawMessage(const QString& message) { - d->m_server.sendMessage(message); + d->sendMessage(message); } #include <qwebchannel.moc> diff --git a/src/qwebsocketserver.cpp b/src/qwebsocketserver.cpp index 81d47e9..a87d4bf 100644 --- a/src/qwebsocketserver.cpp +++ b/src/qwebsocketserver.cpp @@ -86,6 +86,11 @@ QWebSocketServer::QWebSocketServer(QObject* parent) SIGNAL(error(QAbstractSocket::SocketError))); } +QWebSocketServer::~QWebSocketServer() +{ + close(); +} + bool QWebSocketServer::listen(const QHostAddress& address, quint16 port) { return m_server->listen(address, port); @@ -136,7 +141,7 @@ void QWebSocketServer::disconnected() } static const QByteArray headerSwitchProtocols = QByteArrayLiteral("HTTP/1.1 101 Switching Protocols"); -static const QByteArray headerGet = QByteArrayLiteral("GET /"); +static const QByteArray headerGet = QByteArrayLiteral("GET "); static const QByteArray headerHTTP = QByteArrayLiteral("HTTP/1.1"); static const QByteArray headerHost = QByteArrayLiteral("Host: "); static const QByteArray headerUpgrade = QByteArrayLiteral("Upgrade: websocket"); @@ -375,7 +380,7 @@ void QWebSocketServer::sendMessage(const QString& message) sendFrame(Frame::TextFrame, message.toUtf8()); } -void QWebSocketServer::sendFrame(QWebSocketServer::Frame::Opcode opcode, const QByteArray& data) +void QWebSocketServer::sendFrame(Frame::Opcode opcode, const QByteArray& data) { QHash< QTcpSocket*, Connection >::const_iterator it = m_connections.constBegin(); while (it != m_connections.constEnd()) { diff --git a/src/qwebsocketserver.h b/src/qwebsocketserver.h index a660222..875cb58 100644 --- a/src/qwebsocketserver.h +++ b/src/qwebsocketserver.h @@ -53,6 +53,7 @@ class QWebSocketServer : public QObject public: explicit QWebSocketServer(QObject* parent = 0); + virtual ~QWebSocketServer(); bool listen(const QHostAddress& address = QHostAddress::LocalHost, quint16 port = 0); void close(); @@ -99,6 +100,9 @@ protected: bool hasConnection; bool wasUpgraded; }; + virtual bool isValid(const HeaderData& connection); + +private: struct Frame { enum State { @@ -136,9 +140,6 @@ protected: Frame currentFrame; }; - virtual bool isValid(const HeaderData& connection); - -private: void readHeaderData(QTcpSocket* socket, HeaderData& header); void close(QTcpSocket* socket, const HeaderData& header); void upgrade(QTcpSocket* socket, HeaderData& header); diff --git a/src/webchannel.js b/src/webchannel.js index 37e2314..3ee2b0c 100644 --- a/src/webchannel.js +++ b/src/webchannel.js @@ -44,7 +44,7 @@ var QWebChannel = function(baseUrl, initCallback) var channel = this; ///TODO: use ssl? var socketUrl = "ws://" + baseUrl; - this.socket = new WebSocket(socketUrl); + this.socket = new WebSocket(socketUrl, "QWebChannel"); this.send = function(data) { channel.socket.send(JSON.stringify(data)); |