diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2022-11-15 14:12:34 +0100 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2022-11-24 09:39:00 +0000 |
commit | 69e2b30057003c0ed17c3478d60fea249546a168 (patch) | |
tree | 34f8b7bdc7d23e55bfa5a6ddda1b6ff781e599be /src/websockets/qwebsocket_p.cpp | |
parent | 0fbd3decd0dd694063edd06a174f137ec30d3741 (diff) | |
download | qtwebsockets-69e2b30057003c0ed17c3478d60fea249546a168.tar.gz |
QWebSocket: honor subprotocols specified with setRawHeader
We would error out with a ConnectionRejected if the server accepted
one of the protocols specified directly in the header since we
did not consider those at all.
Fixes: QTBUG-108276
Pick-to: 6.4
Change-Id: Ifbb316c9d4871fd764e03c74caefa10f5b757155
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/websockets/qwebsocket_p.cpp')
-rw-r--r-- | src/websockets/qwebsocket_p.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index 294e361..4be504e 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -318,6 +318,24 @@ void QWebSocketPrivate::_q_updateSslConfiguration() #endif +QStringList QWebSocketPrivate::requestedSubProtocols() const +{ + auto subprotocolsRequestedInRawHeader = [this]() { + QStringList protocols; + QByteArray rawProtocols = m_request.rawHeader("Sec-WebSocket-Protocol"); + QLatin1StringView rawProtocolsView(rawProtocols); + const QStringList &optionsProtocols = m_options.subprotocols(); + for (auto &&entry : rawProtocolsView.tokenize(u',', Qt::SkipEmptyParts)) { + if (QLatin1StringView trimmed = entry.trimmed(); !trimmed.isEmpty()) { + if (!optionsProtocols.contains(trimmed)) + protocols << trimmed; + } + } + return protocols; + }; + return m_options.subprotocols() + subprotocolsRequestedInRawHeader(); +} + /*! Called from QWebSocketServer \internal @@ -1002,8 +1020,7 @@ void QWebSocketPrivate::processHandshake(QTcpSocket *pSocket) #endif const QString protocol = QString::fromLatin1(parser.combinedHeaderValue( QByteArrayLiteral("sec-websocket-protocol"))); - - if (!protocol.isEmpty() && !handshakeOptions().subprotocols().contains(protocol)) { + if (!protocol.isEmpty() && !requestedSubProtocols().contains(protocol)) { setErrorString(QWebSocket::tr("WebSocket server has chosen protocol %1 which has not been " "requested") .arg(protocol)); @@ -1096,9 +1113,14 @@ void QWebSocketPrivate::processStateChanged(QAbstractSocket::SocketState socketS QList<QPair<QString, QString> > headers; const auto headerList = m_request.rawHeaderList(); - for (const QByteArray &key : headerList) + for (const QByteArray &key : headerList) { + // protocols handled separately below + if (key.compare("Sec-WebSocket-Protocol", Qt::CaseInsensitive) == 0) + continue; headers << qMakePair(QString::fromLatin1(key), QString::fromLatin1(m_request.rawHeader(key))); + } + const QStringList subProtocols = requestedSubProtocols(); const auto format = QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::RemovePath | QUrl::RemoveQuery @@ -1108,7 +1130,7 @@ void QWebSocketPrivate::processStateChanged(QAbstractSocket::SocketState socketS host, origin(), QString(), - m_options.subprotocols(), + subProtocols, m_key, headers); if (handshake.isEmpty()) { |