1/****************************************************************************
2**
3** Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include <QtTest/QtTest>
29#include <QtTest/qtestcase.h>
30#include <QtCore/QDebug>
31#include <QtCore/QByteArray>
32#include <QtCore/QtEndian>
33
34#include "private/qwebsockethandshakerequest_p.h"
35#include "private/qwebsocketprotocol_p.h"
36#include "QtWebSockets/qwebsocketprotocol.h"
37
38QT_USE_NAMESPACE
39
40Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
41Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode)
42
43const int MAX_HEADERLINE_LENGTH = 8 * 1024;
44const int MAX_HEADERS = 100;
45
46class tst_HandshakeRequest : public QObject
47{
48 Q_OBJECT
49
50public:
51 tst_HandshakeRequest();
52
53private Q_SLOTS:
54 void initTestCase();
55 void cleanupTestCase();
56 void init();
57 void cleanup();
58
59 void tst_initialization();
60
61 void tst_invalidStream_data();
62 void tst_invalidStream();
63
64 void tst_multipleValuesInConnectionHeader();
65 void tst_multipleVersions();
66 void tst_parsingWhitespaceInHeaders();
67
68 void tst_qtbug_39355();
69 void tst_qtbug_48123_data();
70 void tst_qtbug_48123();
71
72 void tst_qtbug_57357_data();
73 void tst_qtbug_57357(); // ipv6 related
74};
75
76tst_HandshakeRequest::tst_HandshakeRequest()
77{}
78
79void tst_HandshakeRequest::initTestCase()
80{
81}
82
83void tst_HandshakeRequest::cleanupTestCase()
84{}
85
86void tst_HandshakeRequest::init()
87{
88 qRegisterMetaType<QWebSocketProtocol::OpCode>(typeName: "QWebSocketProtocol::OpCode");
89 qRegisterMetaType<QWebSocketProtocol::CloseCode>(typeName: "QWebSocketProtocol::CloseCode");
90}
91
92void tst_HandshakeRequest::cleanup()
93{
94}
95
96void tst_HandshakeRequest::tst_initialization()
97{
98 {
99 QWebSocketHandshakeRequest request(0, false);
100 QCOMPARE(request.port(), 0);
101 QVERIFY(!request.isSecure());
102 QVERIFY(!request.isValid());
103 QCOMPARE(request.extensions().length(), 0);
104 QCOMPARE(request.protocols().length(), 0);
105 QCOMPARE(request.headers().size(), 0);
106 QCOMPARE(request.key().length(), 0);
107 QCOMPARE(request.origin().length(), 0);
108 QCOMPARE(request.host().length(), 0);
109 QVERIFY(request.requestUrl().isEmpty());
110 QCOMPARE(request.resourceName().length(), 0);
111 QCOMPARE(request.versions().length(), 0);
112 }
113 {
114 QWebSocketHandshakeRequest request(80, true);
115 QCOMPARE(request.port(), 80);
116 QVERIFY(request.isSecure());
117 QVERIFY(!request.isValid());
118 QCOMPARE(request.extensions().length(), 0);
119 QCOMPARE(request.protocols().length(), 0);
120 QCOMPARE(request.headers().size(), 0);
121 QCOMPARE(request.key().length(), 0);
122 QCOMPARE(request.origin().length(), 0);
123 QCOMPARE(request.host().length(), 0);
124 QVERIFY(request.requestUrl().isEmpty());
125 QCOMPARE(request.resourceName().length(), 0);
126 QCOMPARE(request.versions().length(), 0);
127 }
128 {
129 QWebSocketHandshakeRequest request(80, true);
130 request.clear();
131 QCOMPARE(request.port(), 80);
132 QVERIFY(request.isSecure());
133 QVERIFY(!request.isValid());
134 QCOMPARE(request.extensions().length(), 0);
135 QCOMPARE(request.protocols().length(), 0);
136 QCOMPARE(request.headers().size(), 0);
137 QCOMPARE(request.key().length(), 0);
138 QCOMPARE(request.origin().length(), 0);
139 QCOMPARE(request.host().length(), 0);
140 QVERIFY(request.requestUrl().isEmpty());
141 QCOMPARE(request.resourceName().length(), 0);
142 QCOMPARE(request.versions().length(), 0);
143 }
144}
145
146void tst_HandshakeRequest::tst_invalidStream_data()
147{
148 QTest::addColumn<QString>(name: "dataStream");
149
150 QTest::newRow(dataTag: "garbage on 2 lines") << QStringLiteral("foofoofoo\r\nfoofoo\r\n\r\n");
151 QTest::newRow(dataTag: "garbage on 1 line") << QStringLiteral("foofoofoofoofoo");
152 QTest::newRow(dataTag: "Correctly formatted but invalid fields")
153 << QStringLiteral("VERB RESOURCE PROTOCOL");
154
155 //internally the fields are parsed and indexes are used to convert
156 //to a http version for instance
157 //this test checks if there doesn't occur an out-of-bounds exception
158 QTest::newRow(dataTag: "Correctly formatted but invalid short fields") << QStringLiteral("V R P");
159 QTest::newRow(dataTag: "Invalid \\0 character in header") << QStringLiteral("V R\0 P");
160 QTest::newRow(dataTag: "Invalid HTTP version in header") << QStringLiteral("V R HTTP/invalid");
161 QTest::newRow(dataTag: "Empty header field") << QStringLiteral("GET . HTTP/1.1\r\nHEADER: ");
162 QTest::newRow(dataTag: "All zeros") << QString::fromUtf8(str: QByteArray(10, char(0)));
163 QTest::newRow(dataTag: "Invalid hostname") << QStringLiteral("GET . HTTP/1.1\r\nHost: \xFF\xFF");
164 //doing extensive QStringLiteral concatenations here, because
165 //MSVC 2010 complains when using concatenation literal strings about
166 //concatenation of wide and narrow strings (error C2308)
167 QTest::newRow(dataTag: "Complete header - Invalid WebSocket version")
168 << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: ") +
169 QStringLiteral("\xFF\xFF\r\n") +
170 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
171 QStringLiteral("Upgrade: websocket\r\n") +
172 QStringLiteral("Connection: Upgrade\r\n\r\n");
173 QTest::newRow(dataTag: "Complete header - Invalid verb")
174 << QStringLiteral("XXX . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
175 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
176 QStringLiteral("Upgrade: websocket\r\n") +
177 QStringLiteral("Connection: Upgrade\r\n\r\n");
178 QTest::newRow(dataTag: "Complete header - Invalid HTTP version")
179 << QStringLiteral("GET . HTTP/a.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
180 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
181 QStringLiteral("Upgrade: websocket\r\n") +
182 QStringLiteral("Connection: Upgrade\r\n\r\n");
183 QTest::newRow(dataTag: "Complete header - Invalid connection")
184 << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
185 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
186 QStringLiteral("Upgrade: websocket\r\n") +
187 QStringLiteral("Connection: xxxxxxx\r\n\r\n");
188 QTest::newRow(dataTag: "Complete header - Invalid upgrade")
189 << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
190 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
191 QStringLiteral("Upgrade: wabsocket\r\n") +
192 QStringLiteral("Connection: Upgrade\r\n\r\n");
193 QTest::newRow(dataTag: "Complete header - Upgrade contains too many values")
194 << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
195 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
196 QStringLiteral("Upgrade: websocket,ftp\r\n") +
197 QStringLiteral("Connection: Upgrade\r\n\r\n");
198 QTest::newRow(dataTag: "Invalid header - starts with continuation")
199 << QStringLiteral("GET . HTTP/1.1\r\n Host: foo\r\nSec-WebSocket-Version: 13\r\n") +
200 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
201 QStringLiteral("Upgrade: websocket\r\n") +
202 QStringLiteral("Connection: Upgrade\r\n\r\n");
203 QTest::newRow(dataTag: "Invalid header - no colon")
204 << QStringLiteral("GET . HTTP/1.1\r\nHost: foo\r\nSec-WebSocket-Version: 13\r\n") +
205 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
206 QStringLiteral("Upgrade: websocket\r\n") +
207 QStringLiteral("X-Custom foo\r\n") +
208 QStringLiteral("Connection: Upgrade\r\n\r\n");
209}
210
211void tst_HandshakeRequest::tst_invalidStream()
212{
213 QFETCH(QString, dataStream);
214
215 QByteArray data;
216 QTextStream textStream(&data);
217 QWebSocketHandshakeRequest request(80, true);
218
219 textStream << dataStream;
220 textStream.seek(pos: 0);
221 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
222
223 QVERIFY(!request.isValid());
224 QCOMPARE(request.port(), 80);
225 QVERIFY(request.isSecure());
226 QCOMPARE(request.extensions().length(), 0);
227 QCOMPARE(request.protocols().length(), 0);
228 QCOMPARE(request.headers().size(), 0);
229 QCOMPARE(request.key().length(), 0);
230 QCOMPARE(request.origin().length(), 0);
231 QCOMPARE(request.host().length(), 0);
232 QVERIFY(request.requestUrl().isEmpty());
233 QCOMPARE(request.resourceName().length(), 0);
234 QCOMPARE(request.versions().length(), 0);
235}
236
237/*
238 * This is a regression test
239 * Checks for validity when more than one value is present in Connection
240 */
241void tst_HandshakeRequest::tst_multipleValuesInConnectionHeader()
242{
243 //doing extensive QStringLiteral concatenations here, because
244 //MSVC 2010 complains when using concatenation literal strings about
245 //concatenation of wide and narrow strings (error C2308)
246 QString header = QStringLiteral("GET /test HTTP/1.1\r\nHost: ") +
247 QStringLiteral("foo.com\r\nSec-WebSocket-Version: 13\r\n") +
248 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
249 QStringLiteral("Upgrade: websocket\r\n") +
250 QStringLiteral("Connection: Upgrade,keepalive\r\n\r\n");
251 QByteArray data;
252 QTextStream textStream(&data);
253 QWebSocketHandshakeRequest request(80, false);
254
255 textStream << header;
256 textStream.seek(pos: 0);
257 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
258
259 QVERIFY(request.isValid());
260 QCOMPARE(request.port(), 80);
261 QVERIFY(!request.isSecure());
262 QCOMPARE(request.extensions().length(), 0);
263 QCOMPARE(request.protocols().length(), 0);
264 QCOMPARE(request.headers().size(), 5);
265 QCOMPARE(request.key().length(), 9);
266 QCOMPARE(request.origin().length(), 0);
267 QCOMPARE(request.requestUrl(), QUrl("ws://foo.com/test"));
268 QCOMPARE(request.host(), QStringLiteral("foo.com"));
269 QCOMPARE(request.resourceName().length(), 5);
270 QCOMPARE(request.versions().length(), 1);
271 QCOMPARE(request.versions().at(0), QWebSocketProtocol::Version13);
272}
273
274/*
275 * This is a regression test
276 * Checks for RFC compliant header parsing
277 */
278void tst_HandshakeRequest::tst_parsingWhitespaceInHeaders()
279{
280 //doing extensive QStringLiteral concatenations here, because
281 //MSVC 2010 complains when using concatenation literal strings about
282 //concatenation of wide and narrow strings (error C2308)
283 QString header = QStringLiteral("GET /test HTTP/1.1\r\nHost: ") +
284 QStringLiteral("foo.com\r\nSec-WebSocket-Version:13\r\n") +
285 QStringLiteral("Sec-WebSocket-Key: AVD \r\n\tFBDDFF \r\n") +
286 QStringLiteral("Upgrade:websocket \r\n") +
287 QStringLiteral("Connection: Upgrade,keepalive\r\n\r\n");
288 QByteArray data;
289 QTextStream textStream(&data);
290 QWebSocketHandshakeRequest request(80, false);
291
292 textStream << header;
293 textStream.seek(pos: 0);
294 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
295
296 QVERIFY(request.isValid());
297 QCOMPARE(request.key(), QStringLiteral("AVD FBDDFF"));
298 QCOMPARE(request.versions().length(), 1);
299 QCOMPARE(request.versions().at(0), QWebSocketProtocol::Version13);
300}
301
302void tst_HandshakeRequest::tst_multipleVersions()
303{
304 QString header = QStringLiteral("GET /test HTTP/1.1\r\nHost: foo.com\r\n") +
305 QStringLiteral("Sec-WebSocket-Version: 4, 5, 6, 7, 8, 13\r\n") +
306 QStringLiteral("Sec-WebSocket-Key: AVDFBDDFF\r\n") +
307 QStringLiteral("Upgrade: websocket\r\n") +
308 QStringLiteral("Connection: Upgrade,keepalive\r\n\r\n");
309 QByteArray data;
310 QTextStream textStream(&data);
311 QWebSocketHandshakeRequest request(80, false);
312
313 textStream << header;
314 textStream.seek(pos: 0);
315 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
316
317 QVERIFY(request.isValid());
318 QCOMPARE(request.port(), 80);
319 QVERIFY(!request.isSecure());
320 QCOMPARE(request.extensions().length(), 0);
321 QCOMPARE(request.protocols().length(), 0);
322 QCOMPARE(request.headers().size(), 5);
323 QVERIFY(request.headers().contains(QStringLiteral("host")));
324 QVERIFY(request.headers().contains(QStringLiteral("sec-websocket-version")));
325 QVERIFY(request.headers().contains(QStringLiteral("sec-websocket-key")));
326 QVERIFY(request.headers().contains(QStringLiteral("upgrade")));
327 QVERIFY(request.headers().contains(QStringLiteral("connection")));
328 QCOMPARE(request.key(), QStringLiteral("AVDFBDDFF"));
329 QCOMPARE(request.origin().length(), 0);
330 QCOMPARE(request.requestUrl(), QUrl("ws://foo.com/test"));
331 QCOMPARE(request.host(), QStringLiteral("foo.com"));
332 QCOMPARE(request.resourceName().length(), 5);
333 QCOMPARE(request.versions().length(), 6);
334 //should be 13 since the list is ordered in decreasing order
335 QCOMPARE(request.versions().at(0), QWebSocketProtocol::Version13);
336}
337
338void tst_HandshakeRequest::tst_qtbug_39355()
339{
340 QString header = QStringLiteral("GET /ABC/DEF/ HTTP/1.1\r\nHost: localhost:1234\r\n") +
341 QStringLiteral("Sec-WebSocket-Version: 13\r\n") +
342 QStringLiteral("Sec-WebSocket-Key: 2Wg20829/4ziWlmsUAD8Dg==\r\n") +
343 QStringLiteral("Upgrade: websocket\r\n") +
344 QStringLiteral("Connection: Upgrade\r\n\r\n");
345 QByteArray data;
346 QTextStream textStream(&data);
347 QWebSocketHandshakeRequest request(8080, false);
348
349 textStream << header;
350 textStream.seek(pos: 0);
351 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
352
353 QVERIFY(request.isValid());
354 QCOMPARE(request.port(), 1234);
355 QCOMPARE(request.host(), QStringLiteral("localhost"));
356}
357
358void tst_HandshakeRequest::tst_qtbug_48123_data()
359{
360 QTest::addColumn<QString>(name: "header");
361 QTest::addColumn<bool>(name: "shouldBeValid");
362 const QString header = QStringLiteral("GET /ABC/DEF/ HTTP/1.1\r\nHost: localhost:1234\r\n") +
363 QStringLiteral("Sec-WebSocket-Version: 13\r\n") +
364 QStringLiteral("Sec-WebSocket-Key: 2Wg20829/4ziWlmsUAD8Dg==\r\n") +
365 QStringLiteral("Upgrade: websocket\r\n") +
366 QStringLiteral("Connection: Upgrade\r\n");
367 const int numHeaderLines = header.count(QStringLiteral("\r\n")) - 1; //-1: exclude requestline
368
369 //a headerline should not be larger than MAX_HEADERLINE_LENGTH characters (excluding CRLF)
370 QString illegalHeader = header;
371 illegalHeader.append(s: QString(MAX_HEADERLINE_LENGTH + 1, QLatin1Char('c')));
372 illegalHeader.append(QStringLiteral("\r\n\r\n"));
373
374 QTest::newRow(dataTag: "headerline too long") << illegalHeader << false;
375
376 QString legalHeader = header;
377 const QString headerKey = QStringLiteral("X-CUSTOM-KEY: ");
378 legalHeader.append(s: headerKey);
379 legalHeader.append(s: QString(MAX_HEADERLINE_LENGTH - headerKey.length(), QLatin1Char('c')));
380 legalHeader.append(QStringLiteral("\r\n\r\n"));
381
382 QTest::newRow(dataTag: "headerline with maximum length") << legalHeader << true;
383
384 //a header should not contain more than MAX_HEADERS header lines (excluding the request line)
385 //test with MAX_HEADERS + 1
386 illegalHeader = header;
387 const QString headerLine(QStringLiteral("Host: localhost:1234\r\n"));
388 for (int i = 0; i < (MAX_HEADERS - numHeaderLines + 1); ++i) {
389 illegalHeader.append(s: headerLine);
390 }
391 illegalHeader.append(QStringLiteral("\r\n"));
392
393 QTest::newRow(dataTag: "too many headerlines") << illegalHeader << false;
394
395 //test with MAX_HEADERS header lines (excluding the request line)
396 legalHeader = header;
397 for (int i = 0; i < (MAX_HEADERS - numHeaderLines); ++i) {
398 legalHeader.append(s: headerLine);
399 }
400 legalHeader.append(QStringLiteral("\r\n"));
401
402 QTest::newRow(dataTag: "just enough headerlines") << legalHeader << true;
403}
404
405void tst_HandshakeRequest::tst_qtbug_48123()
406{
407 QFETCH(QString, header);
408 QFETCH(bool, shouldBeValid);
409
410 QByteArray data;
411 QTextStream textStream(&data);
412 QWebSocketHandshakeRequest request(8080, false);
413
414 textStream << header;
415 textStream.seek(pos: 0);
416 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
417
418 QCOMPARE(request.isValid(), shouldBeValid);
419}
420
421void tst_HandshakeRequest::tst_qtbug_57357_data()
422{
423 QTest::addColumn<QString>(name: "header");
424 QTest::addColumn<bool>(name: "valid");
425 QTest::addColumn<QString>(name: "host");
426 QTest::addColumn<int>(name: "port");
427
428 QString header = QLatin1String("GET /ABC/DEF/ HTTP/1.1\r\nHost: %1%2\r\n"
429 "Sec-WebSocket-Version: 13\r\n"
430 "Sec-WebSocket-Key: 2Wg20829/4ziWlmsUAD8Dg==\r\n"
431 "Upgrade: websocket\r\n"
432 "Connection: Upgrade\r\n\r\n");
433
434 QTest::newRow(dataTag: "ipv4-1") << header.arg(QStringLiteral("10.0.0.1")).arg(QStringLiteral(":1234")) << true
435 << QStringLiteral("10.0.0.1")
436 << 1234;
437 QTest::newRow(dataTag: "ipv4-2") << header.arg(QStringLiteral("127.0.0.1")).arg(QStringLiteral(":1111")) << true
438 << QStringLiteral("127.0.0.1")
439 << 1111;
440 QTest::newRow(dataTag: "ipv4-wo-port") << header.arg(QStringLiteral("10.0.0.1")).arg(QStringLiteral("")) << true
441 << QStringLiteral("10.0.0.1")
442 << 8080;
443
444 QTest::newRow(dataTag: "ipv6-1") << header.arg(QStringLiteral("[56:56:56:56:56:56:56:56]")).arg(QStringLiteral(":1234")) << true
445 << QStringLiteral("56:56:56:56:56:56:56:56")
446 << 1234;
447 QTest::newRow(dataTag: "ipv6-2") << header.arg(QStringLiteral("[::ffff:129.144.52.38]")).arg(QStringLiteral(":1111")) << true
448 << QStringLiteral("::ffff:129.144.52.38")
449 << 1111;
450 QTest::newRow(dataTag: "ipv6-wo-port") << header.arg(QStringLiteral("[56:56:56:56:56:56:56:56]")).arg(QStringLiteral("")) << true
451 << QStringLiteral("56:56:56:56:56:56:56:56")
452 << 8080;
453 QTest::newRow(dataTag: "ipv6-invalid-1") << header.arg(QStringLiteral("56:56:56:56:56:56:56:56]")).arg(QStringLiteral(":1234")) << false
454 << QStringLiteral("")
455 << 1234;
456
457 QTest::newRow(dataTag: "host-1") << header.arg(QStringLiteral("foo.com")).arg(QStringLiteral(":1234")) << true
458 << QStringLiteral("foo.com")
459 << 1234;
460 QTest::newRow(dataTag: "host-2") << header.arg(QStringLiteral("bar.net")).arg(QStringLiteral(":1111")) << true
461 << QStringLiteral("bar.net")
462 << 1111;
463 QTest::newRow(dataTag: "host-wo-port") << header.arg(QStringLiteral("foo.com")).arg(QStringLiteral("")) << true
464 << QStringLiteral("foo.com")
465 << 8080;
466
467 QTest::newRow(dataTag: "localhost-1") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral(":1234")) << true
468 << QStringLiteral("localhost")
469 << 1234;
470 QTest::newRow(dataTag: "localhost-2") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral(":1111")) << true
471 << QStringLiteral("localhost")
472 << 1111;
473 QTest::newRow(dataTag: "localhost-wo-port") << header.arg(QStringLiteral("localhost")).arg(QStringLiteral("")) << true
474 << QStringLiteral("localhost")
475 << 8080;
476
477 // reference: qtbase/tests/auto/corelib/io/qurl/tst_qurl.cpp: void tst_QUrl::ipvfuture_data()
478 QTest::newRow(dataTag: "ipvfuture-1") << header.arg(QStringLiteral("[v7.1234]")).arg(QStringLiteral(":1234")) << true
479 << QStringLiteral("v7.1234")
480 << 1234;
481
482 QTest::newRow(dataTag: "invalid-1") << header.arg(QStringLiteral("abc:def@foo.com")).arg(QStringLiteral("")) << false
483 << QStringLiteral("foo.com")
484 << 8080;
485 QTest::newRow(dataTag: "invalid-2") << header.arg(QStringLiteral(":def@foo.com")).arg(QStringLiteral("")) << false
486 << QStringLiteral("foo.com")
487 << 8080;
488 QTest::newRow(dataTag: "invalid-3") << header.arg(QStringLiteral("abc:@foo.com")).arg(QStringLiteral("")) << false
489 << QStringLiteral("foo.com")
490 << 8080;
491 QTest::newRow(dataTag: "invalid-4") << header.arg(QStringLiteral("@foo.com")).arg(QStringLiteral("")) << false
492 << QStringLiteral("foo.com")
493 << 8080;
494 QTest::newRow(dataTag: "invalid-5") << header.arg(QStringLiteral("foo.com/")).arg(QStringLiteral("")) << false
495 << QStringLiteral("foo.com")
496 << 8080;
497}
498
499void tst_HandshakeRequest::tst_qtbug_57357()
500{
501 QFETCH(QString, header);
502 QFETCH(bool, valid);
503 QFETCH(QString, host);
504 QFETCH(int, port);
505
506 QByteArray data;
507 QTextStream textStream(&data);
508 QWebSocketHandshakeRequest request(8080, false);
509
510 textStream << header;
511 textStream.seek(pos: 0);
512 request.readHandshake(textStream, maxHeaderLineLength: MAX_HEADERLINE_LENGTH, maxHeaders: MAX_HEADERS);
513
514 QCOMPARE(request.isValid(), valid);
515 if (valid) {
516 QCOMPARE(request.host(), host);
517 QCOMPARE(request.port(), port);
518 }
519}
520
521QTEST_MAIN(tst_HandshakeRequest)
522
523#include "tst_handshakerequest.moc"
524

source code of qtwebsockets/tests/auto/websockets/handshakerequest/tst_handshakerequest.cpp