summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-12-07 10:07:25 +0100
committerLiang Qi <liang.qi@qt.io>2017-01-06 08:42:14 +0000
commit670266a075c7c312c6a7f9465298bfec0b968ee2 (patch)
tree4e0f34928d5fd786676ab2f4e59cedfbbf35a9e5
parent2eeee81b67ce4fc81793c51bafd2cc1b33076c05 (diff)
downloadqtwebsockets-670266a075c7c312c6a7f9465298bfec0b968ee2.tar.gz
Fix the parser of port in hand shake request
Use QUrl::setAuthority() to parse host and port. The request is invalid when having username or password in Host. Task-number: QTBUG-57357 Change-Id: I4e7c0370794dce15359d372a1e36dc0383083204 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/websockets/qwebsockethandshakerequest.cpp16
-rw-r--r--tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp103
2 files changed, 109 insertions, 10 deletions
diff --git a/src/websockets/qwebsockethandshakerequest.cpp b/src/websockets/qwebsockethandshakerequest.cpp
index 81c5f97..ddeee2d 100644
--- a/src/websockets/qwebsockethandshakerequest.cpp
+++ b/src/websockets/qwebsockethandshakerequest.cpp
@@ -275,16 +275,12 @@ void QWebSocketHandshakeRequest::readHandshake(QTextStream &textStream, int maxH
if (m_requestUrl.isRelative()) {
// see http://tools.ietf.org/html/rfc6455#page-17
// No. 4 item in "The requirements for this handshake"
- int idx = host.indexOf(QStringLiteral(":"));
- bool ok = false;
- int port = 0;
- if (idx != -1) {
- port = host.rightRef(host.length() - idx - 1).toInt(&ok);
- host.truncate(idx);
+ m_requestUrl.setAuthority(host);
+ if (!m_requestUrl.userName().isNull()) { // If the username is null, the password must be too.
+ m_isValid = false;
+ clear();
+ return;
}
- m_requestUrl.setHost(host);
- if (ok)
- m_requestUrl.setPort(port);
}
if (m_requestUrl.scheme().isEmpty()) {
const QString scheme = isSecure() ? QStringLiteral("wss") : QStringLiteral("ws");
@@ -337,7 +333,7 @@ void QWebSocketHandshakeRequest::readHandshake(QTextStream &textStream, int maxH
//TODO: authentication field
- m_isValid = !(host.isEmpty() ||
+ m_isValid = !(m_requestUrl.host().isEmpty() ||
resourceName.isEmpty() ||
m_versions.isEmpty() ||
m_key.isEmpty() ||
diff --git a/tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp b/tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp
index 3419546..4a9603f 100644
--- a/tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp
+++ b/tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp
@@ -67,6 +67,9 @@ private Q_SLOTS:
void tst_qtbug_39355();
void tst_qtbug_48123_data();
void tst_qtbug_48123();
+
+ void tst_qtbug_57357_data();
+ void tst_qtbug_57357(); // ipv6 related
};
tst_HandshakeRequest::tst_HandshakeRequest()
@@ -375,6 +378,106 @@ void tst_HandshakeRequest::tst_qtbug_48123()
QCOMPARE(request.isValid(), shouldBeValid);
}
+void tst_HandshakeRequest::tst_qtbug_57357_data()
+{
+ QTest::addColumn<QString>("header");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<QString>("host");
+ QTest::addColumn<int>("port");
+
+ QString header = QLatin1String("GET /ABC/DEF/ HTTP/1.1\r\nHost: %1%2\r\n"
+ "Sec-WebSocket-Version: 13\r\n"
+ "Sec-WebSocket-Key: 2Wg20829/4ziWlmsUAD8Dg==\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n\r\n");
+
+ QTest::newRow("ipv4-1") << header.arg(QStringLiteral("10.0.0.1")).arg(QStringLiteral(":1234")) << true
+ << QStringLiteral("10.0.0.1")
+ << 1234;
+ QTest::newRow("ipv4-2") << header.arg(QStringLiteral("127.0.0.1")).arg(QStringLiteral(":1111")) << true
+ << QStringLiteral("127.0.0.1")
+ << 1111;
+ QTest::newRow("ipv4-wo-port") << header.arg(QStringLiteral("10.0.0.1")).arg(QStringLiteral("")) << true
+ << QStringLiteral("10.0.0.1")
+ << 8080;
+
+ QTest::newRow("ipv6-1") << header.arg(QStringLiteral("[56:56:56:56:56:56:56:56]")).arg(QStringLiteral(":1234")) << true
+ << QStringLiteral("56:56:56:56:56:56:56:56")
+ << 1234;
+ QTest::newRow("ipv6-2") << header.arg(QStringLiteral("[::ffff:129.144.52.38]")).arg(QStringLiteral(":1111")) << true
+ << QStringLiteral("::ffff:129.144.52.38")
+ << 1111;
+ QTest::newRow("ipv6-wo-port") << header.arg(QStringLiteral("[56:56:56:56:56:56:56:56]")).arg(QStringLiteral("")) << true
+ << QStringLiteral("56:56:56:56:56:56:56:56")
+ << 8080;
+ QTest::newRow("ipv6-invalid-1") << header.arg(QStringLiteral("56:56:56:56:56:56:56:56]")).arg(QStringLiteral(":1234")) << false
+ << QStringLiteral("")
+ << 1234;
+
+ QTest::newRow("host-1") << header.arg(QStringLiteral("foo.com")).arg(QStringLiteral(":1234")) << true
+ << QStringLiteral("foo.com")
+ << 1234;
+ QTest::newRow("host-2") << header.arg(QStringLiteral("bar.net")).arg(QStringLiteral(":1111")) << true
+ << QStringLiteral("bar.net")
+ << 1111;
+ QTest::newRow("host-wo-port") << header.arg(QStringLiteral("foo.com")).arg(QStringLiteral("")) << true
+ << QStringLiteral("foo.com")
+ << 8080;
+
+ QTest::newRow("localhost-1") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral(":1234")) << true
+ << QStringLiteral("localhost")
+ << 1234;
+ QTest::newRow("localhost-2") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral(":1111")) << true
+ << QStringLiteral("localhost")
+ << 1111;
+ QTest::newRow("localhost-wo-port") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral("")) << true
+ << QStringLiteral("localhost")
+ << 8080;
+
+ // reference: qtbase/tests/auto/corelib/io/qurl/tst_qurl.cpp: void tst_QUrl::ipvfuture_data()
+ QTest::newRow("ipvfuture-1") << header.arg(QStringLiteral("[v7.1234]")).arg(QStringLiteral(":1234")) << true
+ << QStringLiteral("v7.1234")
+ << 1234;
+
+ QTest::newRow("invalid-1") << header.arg(QStringLiteral("abc:def@foo.com")).arg(QStringLiteral("")) << false
+ << QStringLiteral("foo.com")
+ << 8080;
+ QTest::newRow("invalid-2") << header.arg(QStringLiteral(":def@foo.com")).arg(QStringLiteral("")) << false
+ << QStringLiteral("foo.com")
+ << 8080;
+ QTest::newRow("invalid-3") << header.arg(QStringLiteral("abc:@foo.com")).arg(QStringLiteral("")) << false
+ << QStringLiteral("foo.com")
+ << 8080;
+ QTest::newRow("invalid-4") << header.arg(QStringLiteral("@foo.com")).arg(QStringLiteral("")) << false
+ << QStringLiteral("foo.com")
+ << 8080;
+ QTest::newRow("invalid-5") << header.arg(QStringLiteral("foo.com/")).arg(QStringLiteral("")) << false
+ << QStringLiteral("foo.com")
+ << 8080;
+}
+
+void tst_HandshakeRequest::tst_qtbug_57357()
+{
+ QFETCH(QString, header);
+ QFETCH(bool, valid);
+ QFETCH(QString, host);
+ QFETCH(int, port);
+
+ QByteArray data;
+ QTextStream textStream(&data);
+ QWebSocketHandshakeRequest request(8080, false);
+
+ textStream << header;
+ textStream.seek(0);
+ request.readHandshake(textStream, MAX_HEADERLINE_LENGTH, MAX_HEADERS);
+
+ QCOMPARE(request.isValid(), valid);
+ if (valid) {
+ QCOMPARE(request.host(), host);
+ QCOMPARE(request.port(), port);
+ }
+}
+
QTEST_MAIN(tst_HandshakeRequest)
#include "tst_handshakerequest.moc"