1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
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 | |
29 | |
30 | #include <QtTest/QtTest> |
31 | #include <QtCore/QJsonArray> |
32 | #include <QtCore/QJsonDocument> |
33 | #include <QtCore/QJsonObject> |
34 | #include <QtCore/QJsonValue> |
35 | #include <QtNetwork/QNetworkCookieJar> |
36 | #include <QtNetwork/QNetworkCookie> |
37 | #include <QtNetwork/QNetworkRequest> |
38 | #if QT_CONFIG(topleveldomain) |
39 | #include "private/qtldurl_p.h" |
40 | #endif |
41 | |
42 | class tst_QNetworkCookieJar: public QObject |
43 | { |
44 | Q_OBJECT |
45 | |
46 | private slots: |
47 | void getterSetter(); |
48 | void setCookiesFromUrl_data(); |
49 | void setCookiesFromUrl(); |
50 | void cookiesForUrl_data(); |
51 | void cookiesForUrl(); |
52 | #if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain) |
53 | void effectiveTLDs_data(); |
54 | void effectiveTLDs(); |
55 | #endif |
56 | void rfc6265_data(); |
57 | void rfc6265(); |
58 | }; |
59 | |
60 | class MyCookieJar: public QNetworkCookieJar |
61 | { |
62 | public: |
63 | ~MyCookieJar() override; |
64 | using QNetworkCookieJar::allCookies; |
65 | using QNetworkCookieJar::setAllCookies; |
66 | }; |
67 | |
68 | MyCookieJar::~MyCookieJar() = default; |
69 | |
70 | void tst_QNetworkCookieJar::getterSetter() |
71 | { |
72 | MyCookieJar jar; |
73 | |
74 | QVERIFY(jar.allCookies().isEmpty()); |
75 | |
76 | QList<QNetworkCookie> list; |
77 | QNetworkCookie cookie; |
78 | cookie.setName("a" ); |
79 | list << cookie; |
80 | |
81 | jar.setAllCookies(list); |
82 | QCOMPARE(jar.allCookies(), list); |
83 | } |
84 | |
85 | void tst_QNetworkCookieJar::setCookiesFromUrl_data() |
86 | { |
87 | QTest::addColumn<QList<QNetworkCookie> >(name: "preset" ); |
88 | QTest::addColumn<QNetworkCookie>(name: "newCookie" ); |
89 | QTest::addColumn<QString>(name: "referenceUrl" ); |
90 | QTest::addColumn<QList<QNetworkCookie> >(name: "expectedResult" ); |
91 | QTest::addColumn<bool>(name: "setCookies" ); |
92 | |
93 | QList<QNetworkCookie> preset; |
94 | QList<QNetworkCookie> result; |
95 | QNetworkCookie cookie; |
96 | |
97 | cookie.setName("a" ); |
98 | cookie.setPath("/" ); |
99 | cookie.setDomain(".foo.tld" ); |
100 | result += cookie; |
101 | QTest::newRow(dataTag: "just-add" ) << preset << cookie << "http://www.foo.tld" << result << true; |
102 | |
103 | preset = result; |
104 | QTest::newRow(dataTag: "replace-1" ) << preset << cookie << "http://www.foo.tld" << result << true; |
105 | |
106 | cookie.setValue("bc" ); |
107 | result.clear(); |
108 | result += cookie; |
109 | QTest::newRow(dataTag: "replace-2" ) << preset << cookie << "http://www.foo.tld" << result << true; |
110 | |
111 | preset = result; |
112 | cookie.setName("d" ); |
113 | result += cookie; |
114 | QTest::newRow(dataTag: "append" ) << preset << cookie << "http://www.foo.tld" << result << true; |
115 | |
116 | cookie = preset.at(i: 0); |
117 | result = preset; |
118 | cookie.setPath("/something" ); |
119 | result += cookie; |
120 | QTest::newRow(dataTag: "diff-path" ) << preset << cookie << "http://www.foo.tld/something" << result << true; |
121 | |
122 | preset.clear(); |
123 | preset += cookie; |
124 | cookie.setPath("/" ); |
125 | QTest::newRow(dataTag: "diff-path-order" ) << preset << cookie << "http://www.foo.tld" << result << true; |
126 | |
127 | preset.clear(); |
128 | result.clear(); |
129 | QNetworkCookie finalCookie = cookie; |
130 | cookie.setDomain("foo.tld" ); |
131 | finalCookie.setDomain(".foo.tld" ); |
132 | result += finalCookie; |
133 | QTest::newRow(dataTag: "should-add-dot-prefix" ) << preset << cookie << "http://www.foo.tld" << result << true; |
134 | |
135 | result.clear(); |
136 | cookie.setDomain("" ); |
137 | finalCookie.setDomain("www.foo.tld" ); |
138 | result += finalCookie; |
139 | QTest::newRow(dataTag: "should-set-default-domain" ) << preset << cookie << "http://www.foo.tld" << result << true; |
140 | |
141 | // security test: |
142 | result.clear(); |
143 | preset.clear(); |
144 | cookie.setDomain("something.completely.different" ); |
145 | QTest::newRow(dataTag: "security-domain-1" ) << preset << cookie << "http://www.foo.tld" << result << false; |
146 | |
147 | // we want the cookie to be accepted although the path does not match, see QTBUG-5815 |
148 | cookie.setDomain(".foo.tld" ); |
149 | cookie.setPath("/something" ); |
150 | result += cookie; |
151 | QTest::newRow(dataTag: "security-path-1" ) << preset << cookie << "http://www.foo.tld" << result << true; |
152 | |
153 | // check effective TLDs |
154 | // 1. co.uk is an effective TLD, should be denied |
155 | result.clear(); |
156 | preset.clear(); |
157 | cookie.setPath("/" ); |
158 | cookie.setDomain(".co.uk" ); |
159 | QTest::newRow(dataTag: "effective-tld1-denied" ) << preset << cookie << "http://something.co.uk" << result << false; |
160 | cookie.setDomain("co.uk" ); |
161 | QTest::newRow(dataTag: "effective-tld1-denied2" ) << preset << cookie << "http://something.co.uk" << result << false; |
162 | cookie.setDomain(".something.co.uk" ); |
163 | result += cookie; |
164 | QTest::newRow(dataTag: "effective-tld1-accepted" ) << preset << cookie << "http://something.co.uk" << result << true; |
165 | |
166 | // 2. anything .ck is an effective TLD ('*.ck'), but 'www.ck' is an exception |
167 | result.clear(); |
168 | preset.clear(); |
169 | cookie.setDomain(".ck" ); |
170 | QTest::newRow(dataTag: "effective-tld.ck-denied" ) << preset << cookie << "http://foo.ck" << result << false; |
171 | result.clear(); |
172 | preset.clear(); |
173 | cookie.setDomain(".foo.ck" ); |
174 | result += cookie; |
175 | QTest::newRow(dataTag: "effective-tld2-accepted2" ) << preset << cookie << "http://foo.ck" << result << true; |
176 | result.clear(); |
177 | QTest::newRow(dataTag: "effective-tld2-denied2" ) << preset << cookie << "http://www.foo.ck" << result << false; |
178 | QTest::newRow(dataTag: "effective-tld2-denied3" ) << preset << cookie << "http://www.anything.foo.ck" << result << false; |
179 | cookie.setDomain(".www.ck" ); |
180 | result += cookie; |
181 | QTest::newRow(dataTag: "effective-tld2-accepted" ) << preset << cookie << "http://www.www.ck" << result << true; |
182 | |
183 | result.clear(); |
184 | preset.clear(); |
185 | cookie.setDomain("127.0.0.1" ); |
186 | result += cookie; |
187 | QTest::newRow(dataTag: "IPv4-address-as-domain" ) << preset << cookie << "http://127.0.0.1/" << result << true; |
188 | |
189 | result.clear(); |
190 | preset.clear(); |
191 | cookie.setDomain("fe80::250:56ff:fec0:1" ); |
192 | result += cookie; |
193 | QTest::newRow(dataTag: "IPv6-address-as-domain" ) << preset << cookie << "http://[fe80::250:56ff:fec0:1]/" << result << true; |
194 | |
195 | // setting the defaults: |
196 | finalCookie = cookie; |
197 | finalCookie.setPath("/something/" ); |
198 | finalCookie.setDomain("www.foo.tld" ); |
199 | cookie.setPath("" ); |
200 | cookie.setDomain("" ); |
201 | result.clear(); |
202 | result += finalCookie; |
203 | QTest::newRow(dataTag: "defaults-1" ) << preset << cookie << "http://www.foo.tld/something/" << result << true; |
204 | |
205 | finalCookie.setPath("/" ); |
206 | result.clear(); |
207 | result += finalCookie; |
208 | QTest::newRow(dataTag: "defaults-2" ) << preset << cookie << "http://www.foo.tld" << result << true; |
209 | |
210 | // security test: do not accept cookie domains like ".com" nor ".com." (see RFC 2109 section 4.3.2) |
211 | result.clear(); |
212 | preset.clear(); |
213 | cookie.setDomain(".com" ); |
214 | QTest::newRow(dataTag: "rfc2109-4.3.2-ex3" ) << preset << cookie << "http://x.foo.com" << result << false; |
215 | |
216 | result.clear(); |
217 | preset.clear(); |
218 | cookie.setDomain(".com." ); |
219 | QTest::newRow(dataTag: "rfc2109-4.3.2-ex3-2" ) << preset << cookie << "http://x.foo.com" << result << false; |
220 | |
221 | // When using a TLD as a hostname the hostname should still get cookies (QTBUG-52040) |
222 | // ... and nothing else should get the cookies. |
223 | result.clear(); |
224 | preset.clear(); |
225 | cookie.setPath("/" ); |
226 | cookie.setDomain(".support" ); |
227 | result += cookie; |
228 | QTest::newRow(dataTag: "TLD-as-domain-accepted" ) << preset << cookie << "http://support" << result << true; |
229 | result.clear(); |
230 | QTest::newRow(dataTag: "TLD-as-domain-rejected" ) << preset << cookie << "http://a.support" << result << false; |
231 | // Now test with no domain in the cookie, use the domain from the url (matching TLD) |
232 | cookie.setDomain("support" ); |
233 | result += cookie; |
234 | cookie.setDomain("" ); |
235 | QTest::newRow(dataTag: "TLD-as-domain-accepted2" ) << preset << cookie << "http://support" << result << true; |
236 | } |
237 | |
238 | void tst_QNetworkCookieJar::setCookiesFromUrl() |
239 | { |
240 | QFETCH(QList<QNetworkCookie>, preset); |
241 | QFETCH(QNetworkCookie, newCookie); |
242 | QFETCH(QString, referenceUrl); |
243 | QFETCH(QList<QNetworkCookie>, expectedResult); |
244 | QFETCH(bool, setCookies); |
245 | |
246 | QList<QNetworkCookie> cookieList; |
247 | cookieList += newCookie; |
248 | MyCookieJar jar; |
249 | jar.setAllCookies(preset); |
250 | QCOMPARE(jar.setCookiesFromUrl(cookieList, referenceUrl), setCookies); |
251 | |
252 | QList<QNetworkCookie> result = jar.allCookies(); |
253 | foreach (QNetworkCookie cookie, expectedResult) { |
254 | QVERIFY2(result.contains(cookie), cookie.toRawForm()); |
255 | result.removeAll(t: cookie); |
256 | } |
257 | QVERIFY2(result.isEmpty(), QTest::toString(result)); |
258 | } |
259 | |
260 | void tst_QNetworkCookieJar::cookiesForUrl_data() |
261 | { |
262 | QTest::addColumn<QList<QNetworkCookie> >(name: "allCookies" ); |
263 | QTest::addColumn<QString>(name: "url" ); |
264 | QTest::addColumn<QList<QNetworkCookie> >(name: "expectedResult" ); |
265 | |
266 | QList<QNetworkCookie> allCookies; |
267 | QList<QNetworkCookie> result; |
268 | |
269 | QTest::newRow(dataTag: "no-cookies" ) << allCookies << "http://foo.bar/" << result; |
270 | |
271 | QNetworkCookie cookie; |
272 | cookie.setName("a" ); |
273 | cookie.setPath("/web" ); |
274 | cookie.setDomain(".qt-project.org" ); |
275 | allCookies += cookie; |
276 | |
277 | QTest::newRow(dataTag: "no-match-1" ) << allCookies << "http://foo.bar/" << result; |
278 | QTest::newRow(dataTag: "no-match-2" ) << allCookies << "http://foo.bar/web" << result; |
279 | QTest::newRow(dataTag: "no-match-3" ) << allCookies << "http://foo.bar/web/wiki" << result; |
280 | QTest::newRow(dataTag: "no-match-4" ) << allCookies << "http://qt-project.org" << result; |
281 | QTest::newRow(dataTag: "no-match-5" ) << allCookies << "http://qt-project.org" << result; |
282 | QTest::newRow(dataTag: "no-match-6" ) << allCookies << "http://qt-project.org/webinar" << result; |
283 | QTest::newRow(dataTag: "no-match-7" ) << allCookies << "http://qt-project.org/webinar" << result; |
284 | QTest::newRow(dataTag: "no-match-8" ) << allCookies << "http://qt-project.org./web" << result; |
285 | QTest::newRow(dataTag: "no-match-9" ) << allCookies << "http://qt-project.org./web" << result; |
286 | |
287 | result = allCookies; |
288 | QTest::newRow(dataTag: "match-1" ) << allCookies << "http://qt-project.org/web" << result; |
289 | QTest::newRow(dataTag: "match-2" ) << allCookies << "http://qt-project.org/web/" << result; |
290 | QTest::newRow(dataTag: "match-3" ) << allCookies << "http://qt-project.org/web/content" << result; |
291 | QTest::newRow(dataTag: "match-4" ) << allCookies << "http://qt-project.org/web" << result; |
292 | QTest::newRow(dataTag: "match-5" ) << allCookies << "http://qt-project.org/web/" << result; |
293 | QTest::newRow(dataTag: "match-6" ) << allCookies << "http://qt-project.org/web/content" << result; |
294 | |
295 | cookie.setPath("/web/wiki" ); |
296 | allCookies += cookie; |
297 | |
298 | // exact same results as before: |
299 | QTest::newRow(dataTag: "one-match-1" ) << allCookies << "http://qt-project.org/web" << result; |
300 | QTest::newRow(dataTag: "one-match-2" ) << allCookies << "http://qt-project.org/web/" << result; |
301 | QTest::newRow(dataTag: "one-match-3" ) << allCookies << "http://qt-project.org/web/content" << result; |
302 | QTest::newRow(dataTag: "one-match-4" ) << allCookies << "http://qt-project.org/web" << result; |
303 | QTest::newRow(dataTag: "one-match-5" ) << allCookies << "http://qt-project.org/web/" << result; |
304 | QTest::newRow(dataTag: "one-match-6" ) << allCookies << "http://qt-project.org/web/content" << result; |
305 | |
306 | result.prepend(t: cookie); // longer path, it must match first |
307 | QTest::newRow(dataTag: "two-matches-1" ) << allCookies << "http://qt-project.org/web/wiki" << result; |
308 | QTest::newRow(dataTag: "two-matches-2" ) << allCookies << "http://qt-project.org/web/wiki" << result; |
309 | |
310 | // invert the order; |
311 | allCookies.clear(); |
312 | allCookies << result.at(i: 1) << result.at(i: 0); |
313 | QTest::newRow(dataTag: "two-matches-3" ) << allCookies << "http://qt-project.org/web/wiki" << result; |
314 | QTest::newRow(dataTag: "two-matches-4" ) << allCookies << "http://qt-project.org/web/wiki" << result; |
315 | |
316 | // expired cookie |
317 | allCookies.clear(); |
318 | cookie.setExpirationDate(QDateTime::fromString(s: "09-Nov-1999" , format: "dd-MMM-yyyy" )); |
319 | allCookies += cookie; |
320 | result.clear(); |
321 | QTest::newRow(dataTag: "exp-match-1" ) << allCookies << "http://qt-project.org/web" << result; |
322 | QTest::newRow(dataTag: "exp-match-2" ) << allCookies << "http://qt-project.org/web/" << result; |
323 | QTest::newRow(dataTag: "exp-match-3" ) << allCookies << "http://qt-project.org/web/content" << result; |
324 | QTest::newRow(dataTag: "exp-match-4" ) << allCookies << "http://qt-project.org/web" << result; |
325 | QTest::newRow(dataTag: "exp-match-5" ) << allCookies << "http://qt-project.org/web/" << result; |
326 | QTest::newRow(dataTag: "exp-match-6" ) << allCookies << "http://qt-project.org/web/content" << result; |
327 | |
328 | // path matching |
329 | allCookies.clear(); |
330 | QNetworkCookie anotherCookie; |
331 | anotherCookie.setName("a" ); |
332 | anotherCookie.setPath("/web" ); |
333 | anotherCookie.setDomain(".qt-project.org" ); |
334 | allCookies += anotherCookie; |
335 | result.clear(); |
336 | QTest::newRow(dataTag: "path-unmatch-1" ) << allCookies << "http://qt-project.org/" << result; |
337 | QTest::newRow(dataTag: "path-unmatch-2" ) << allCookies << "http://qt-project.org/something/else" << result; |
338 | result += anotherCookie; |
339 | QTest::newRow(dataTag: "path-match-1" ) << allCookies << "http://qt-project.org/web" << result; |
340 | QTest::newRow(dataTag: "path-match-2" ) << allCookies << "http://qt-project.org/web/" << result; |
341 | QTest::newRow(dataTag: "path-match-3" ) << allCookies << "http://qt-project.org/web/content" << result; |
342 | |
343 | // secure cookies |
344 | allCookies.clear(); |
345 | result.clear(); |
346 | QNetworkCookie secureCookie; |
347 | secureCookie.setName("a" ); |
348 | secureCookie.setPath("/web" ); |
349 | secureCookie.setDomain(".qt-project.org" ); |
350 | secureCookie.setSecure(true); |
351 | allCookies += secureCookie; |
352 | QTest::newRow(dataTag: "no-match-secure-1" ) << allCookies << "http://qt-project.org/web" << result; |
353 | QTest::newRow(dataTag: "no-match-secure-2" ) << allCookies << "http://qt-project.org/web" << result; |
354 | result += secureCookie; |
355 | QTest::newRow(dataTag: "match-secure-1" ) << allCookies << "https://qt-project.org/web" << result; |
356 | QTest::newRow(dataTag: "match-secure-2" ) << allCookies << "https://qt-project.org/web" << result; |
357 | |
358 | // domain ending in . |
359 | allCookies.clear(); |
360 | result.clear(); |
361 | QNetworkCookie cookieDot; |
362 | cookieDot.setDomain(".example.com." ); |
363 | cookieDot.setName("a" ); |
364 | allCookies += cookieDot; |
365 | QTest::newRow(dataTag: "no-match-domain-dot" ) << allCookies << "http://example.com" << result; |
366 | result += cookieDot; |
367 | QTest::newRow(dataTag: "match-domain-dot" ) << allCookies << "http://example.com." << result; |
368 | |
369 | // Root path in cookie, empty url path |
370 | allCookies.clear(); |
371 | QNetworkCookie rootCookie; |
372 | rootCookie.setName("a" ); |
373 | rootCookie.setPath("/" ); |
374 | rootCookie.setDomain("qt-project.org" ); |
375 | allCookies += rootCookie; |
376 | result.clear(); |
377 | result += rootCookie; |
378 | QTest::newRow(dataTag: "root-path-match" ) << allCookies << "http://qt-project.org" << result; |
379 | |
380 | // Domain in cookie happens to match a TLD |
381 | allCookies.clear(); |
382 | QNetworkCookie tldCookie; |
383 | tldCookie.setDomain(".support" ); |
384 | tldCookie.setName("a" ); |
385 | tldCookie.setValue("b" ); |
386 | allCookies += tldCookie; |
387 | result.clear(); |
388 | result += tldCookie; |
389 | QTest::newRow(dataTag: "tld-cookie-match" ) << allCookies << "http://support/" << result; |
390 | result.clear(); |
391 | QTest::newRow(dataTag: "tld-cookie-no-match" ) << allCookies << "http://a.support/" << result; |
392 | } |
393 | |
394 | void tst_QNetworkCookieJar::cookiesForUrl() |
395 | { |
396 | QFETCH(QList<QNetworkCookie>, allCookies); |
397 | QFETCH(QString, url); |
398 | QFETCH(QList<QNetworkCookie>, expectedResult); |
399 | |
400 | MyCookieJar jar; |
401 | jar.setAllCookies(allCookies); |
402 | |
403 | QList<QNetworkCookie> result = jar.cookiesForUrl(url); |
404 | QCOMPARE(result, expectedResult); |
405 | } |
406 | |
407 | // This test requires private API. |
408 | #if defined(QT_BUILD_INTERNAL) && QT_CONFIG(topleveldomain) |
409 | void tst_QNetworkCookieJar::effectiveTLDs_data() |
410 | { |
411 | QTest::addColumn<QString>(name: "domain" ); |
412 | QTest::addColumn<bool>(name: "isTLD" ); |
413 | |
414 | QTest::newRow(dataTag: "yes1" ) << "com" << true; |
415 | QTest::newRow(dataTag: "yes2" ) << "de" << true; |
416 | QTest::newRow(dataTag: "yes3" ) << "ulm.museum" << true; |
417 | QTest::newRow(dataTag: "yes4" ) << "krodsherad.no" << true; |
418 | QTest::newRow(dataTag: "yes5" ) << "1.bg" << true; |
419 | QTest::newRow(dataTag: "yes6" ) << "com.cn" << true; |
420 | QTest::newRow(dataTag: "yes7" ) << "org.ws" << true; |
421 | QTest::newRow(dataTag: "yes8" ) << "co.uk" << true; |
422 | QTest::newRow(dataTag: "yes9" ) << "wallonie.museum" << true; |
423 | QTest::newRow(dataTag: "yes10" ) << "hk.com" << true; |
424 | QTest::newRow(dataTag: "yes11" ) << "hk.org" << true; |
425 | |
426 | QTest::newRow(dataTag: "no1" ) << "anything.com" << false; |
427 | QTest::newRow(dataTag: "no2" ) << "anything.de" << false; |
428 | QTest::newRow(dataTag: "no3" ) << "eselsberg.ulm.museum" << false; |
429 | QTest::newRow(dataTag: "no4" ) << "noe.krodsherad.no" << false; |
430 | QTest::newRow(dataTag: "no5" ) << "2.1.bg" << false; |
431 | QTest::newRow(dataTag: "no6" ) << "foo.com.cn" << false; |
432 | QTest::newRow(dataTag: "no7" ) << "something.org.ws" << false; |
433 | QTest::newRow(dataTag: "no8" ) << "teatime.co.uk" << false; |
434 | QTest::newRow(dataTag: "no9" ) << "bla" << false; |
435 | QTest::newRow(dataTag: "no10" ) << "bla.bla" << false; |
436 | QTest::newRow(dataTag: "no11" ) << "mosreg.ru" << false; |
437 | |
438 | const ushort s1[] = {0x74, 0x72, 0x61, 0x6e, 0xf8, 0x79, 0x2e, 0x6e, 0x6f, 0x00}; // xn--trany-yua.no |
439 | const ushort s2[] = {0x5d9, 0x5e8, 0x5d5, 0x5e9, 0x5dc, 0x5d9, 0x5dd, 0x2e, 0x6d, 0x75, 0x73, 0x65, 0x75, 0x6d, 0x00}; // xn--9dbhblg6di.museum |
440 | const ushort s3[] = {0x7ec4, 0x7e54, 0x2e, 0x68, 0x6b, 0x00}; // xn--mk0axi.hk |
441 | const ushort s4[] = {0x7f51, 0x7edc, 0x2e, 0x63, 0x6e, 0x00}; // xn--io0a7i.cn |
442 | const ushort s5[] = {0x72, 0xe1, 0x68, 0x6b, 0x6b, 0x65, 0x72, 0xe1, 0x76, 0x6a, 0x75, 0x2e, 0x6e, 0x6f, 0x00}; // xn--rhkkervju-01af.no |
443 | const ushort s6[] = {0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x00}; // xn--clchc0ea0b2g2a9gcd |
444 | const ushort s7[] = {0x627, 0x644, 0x627, 0x631, 0x62f, 0x646, 0x00}; // xn--mgbayh7gpa |
445 | const ushort s8[] = {0x63, 0x6f, 0x72, 0x72, 0x65, 0x69, 0x6f, 0x73, 0x2d, 0x65, 0x2d, 0x74, 0x65, 0x6c, 0x65, |
446 | 0x63, 0x6f, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0xe7, 0xf5, 0x65, 0x73, 0x2e, 0x6d, 0x75, |
447 | 0x73, 0x65, 0x75, 0x6d, 0x00}; // xn--correios-e-telecomunicaes-ghc29a.museum |
448 | QTest::newRow(dataTag: "yes-specialchars1" ) << QString::fromUtf16(s1) << true; |
449 | QTest::newRow(dataTag: "yes-specialchars2" ) << QString::fromUtf16(s2) << true; |
450 | QTest::newRow(dataTag: "yes-specialchars3" ) << QString::fromUtf16(s3) << true; |
451 | QTest::newRow(dataTag: "yes-specialchars4" ) << QString::fromUtf16(s4) << true; |
452 | QTest::newRow(dataTag: "yes-specialchars5" ) << QString::fromUtf16(s5) << true; |
453 | QTest::newRow(dataTag: "yes-specialchars6" ) << QString::fromUtf16(s6) << true; |
454 | QTest::newRow(dataTag: "yes-specialchars7" ) << QString::fromUtf16(s7) << true; |
455 | QTest::newRow(dataTag: "yes-specialchars8" ) << QString::fromUtf16(s8) << true; |
456 | |
457 | QTest::newRow(dataTag: "no-specialchars1" ) << QString::fromUtf16(s1).prepend(s: "something" ) << false; |
458 | QTest::newRow(dataTag: "no-specialchars2" ) << QString::fromUtf16(s2).prepend(s: QString::fromUtf16(s2)) << false; |
459 | QTest::newRow(dataTag: "no-specialchars2.5" ) << QString::fromUtf16(s2).prepend(s: "whatever" ) << false; |
460 | QTest::newRow(dataTag: "no-specialchars3" ) << QString::fromUtf16(s3).prepend(s: "foo" ) << false; |
461 | QTest::newRow(dataTag: "no-specialchars4" ) << QString::fromUtf16(s4).prepend(s: "bar" ) << false; |
462 | QTest::newRow(dataTag: "no-specialchars5" ) << QString::fromUtf16(s5).prepend(s: QString::fromUtf16(s2)) << false; |
463 | QTest::newRow(dataTag: "no-specialchars6" ) << QString::fromUtf16(s6).prepend(s: QLatin1Char('.') + QString::fromUtf16(s6)) << false; |
464 | QTest::newRow(dataTag: "no-specialchars7" ) << QString::fromUtf16(s7).prepend(s: "bla" ) << false; |
465 | QTest::newRow(dataTag: "no-specialchars8" ) << QString::fromUtf16(s8).append(s: "foo" ) << false; |
466 | |
467 | QTest::newRow(dataTag: "exception1" ) << "pref.iwate.jp" << false; |
468 | QTest::newRow(dataTag: "exception2" ) << "omanpost.om" << false; |
469 | QTest::newRow(dataTag: "exception3" ) << "omantel.om" << false; |
470 | QTest::newRow(dataTag: "exception4" ) << "gobiernoelectronico.ar" << false; |
471 | QTest::newRow(dataTag: "exception5" ) << "pref.ishikawa.jp" << false; |
472 | |
473 | QTest::newRow(dataTag: "yes-wildcard1" ) << "*.jm" << true; |
474 | QTest::newRow(dataTag: "yes-wildcard1.5" ) << "anything.jm" << true; |
475 | QTest::newRow(dataTag: "yes-wildcard2" ) << "something.kh" << true; |
476 | QTest::newRow(dataTag: "no-wildcard3" ) << "whatever.uk" << false; // was changed at some point |
477 | QTest::newRow(dataTag: "yes-wildcard4" ) << "anything.sendai.jp" << true; |
478 | QTest::newRow(dataTag: "yes-wildcard5" ) << "foo.sch.uk" << true; |
479 | QTest::newRow(dataTag: "yes-platform.sh" ) << "eu.platform.sh" << true; |
480 | QTest::newRow(dataTag: "no-platform.sh" ) << "something.platform.sh" << false; |
481 | } |
482 | |
483 | void tst_QNetworkCookieJar::effectiveTLDs() |
484 | { |
485 | QFETCH(QString, domain); |
486 | QFETCH(bool, isTLD); |
487 | QCOMPARE(qIsEffectiveTLD(domain), isTLD); |
488 | } |
489 | #endif |
490 | |
491 | void tst_QNetworkCookieJar::rfc6265_data() |
492 | { |
493 | QTest::addColumn<QStringList>(name: "received" ); |
494 | QTest::addColumn<QList<QNetworkCookie> >(name: "sent" ); |
495 | QTest::addColumn<QString>(name: "sentTo" ); |
496 | |
497 | QFile file(QFINDTESTDATA("parser.json" )); |
498 | QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
499 | QJsonDocument document; |
500 | document = QJsonDocument::fromJson(json: file.readAll()); |
501 | QVERIFY(!document.isNull()); |
502 | QVERIFY(document.isArray()); |
503 | |
504 | foreach (const QJsonValue& testCase, document.array()) { |
505 | QJsonObject testObject = testCase.toObject(); |
506 | |
507 | //"test" - the test case name |
508 | QString testCaseName = testObject.value(key: "test" ).toString(); |
509 | if (testCaseName.toLower().startsWith(s: "disabled" )) |
510 | continue; |
511 | |
512 | //"received" - the cookies received from the server |
513 | QJsonArray received = testObject.value(key: "received" ).toArray(); |
514 | QStringList receivedList; |
515 | foreach (const QJsonValue& receivedCookie, received) |
516 | receivedList.append(t: receivedCookie.toString()); |
517 | |
518 | //"sent" - the cookies sent back to the server |
519 | QJsonArray sent = testObject.value(key: "sent" ).toArray(); |
520 | QList<QNetworkCookie> sentList; |
521 | foreach (const QJsonValue& sentCookie, sent) { |
522 | QJsonObject sentCookieObject = sentCookie.toObject(); |
523 | QNetworkCookie cookie; |
524 | cookie.setName(sentCookieObject.value(key: "name" ).toString().toUtf8()); |
525 | cookie.setValue(sentCookieObject.value(key: "value" ).toString().toUtf8()); |
526 | sentList.append(t: cookie); |
527 | } |
528 | |
529 | //"sent-to" - the relative url where cookies are sent |
530 | QTest::newRow(qPrintable(testCaseName)) << receivedList << sentList << testObject.value(key: "sent-to" ).toString(); |
531 | } |
532 | } |
533 | |
534 | void tst_QNetworkCookieJar::rfc6265() |
535 | { |
536 | QFETCH(QStringList, received); |
537 | QFETCH(QList<QNetworkCookie>, sent); |
538 | QFETCH(QString, sentTo); |
539 | |
540 | QUrl receivedUrl("http://home.example.org:8888/cookie-parser" ); |
541 | QUrl sentUrl("http://home.example.org:8888/cookie-parser-result" ); |
542 | if (!sentTo.isEmpty()) |
543 | sentUrl = receivedUrl.resolved(relative: sentTo); |
544 | |
545 | QNetworkCookieJar jar; |
546 | QList<QNetworkCookie> receivedCookies; |
547 | foreach (const QString &cookieLine, received) |
548 | receivedCookies.append(t: QNetworkCookie::parseCookies(cookieString: cookieLine.toUtf8())); |
549 | |
550 | jar.setCookiesFromUrl(cookieList: receivedCookies, url: receivedUrl); |
551 | QList<QNetworkCookie> cookiesToSend = jar.cookiesForUrl(url: sentUrl); |
552 | |
553 | //compare cookies only using name/value, as the metadata isn't sent over the network |
554 | QCOMPARE(cookiesToSend.count(), sent.count()); |
555 | bool ok = true; |
556 | for (int i = 0; i < cookiesToSend.count(); i++) { |
557 | if (cookiesToSend.at(i).name() != sent.at(i).name()) { |
558 | ok = false; |
559 | break; |
560 | } |
561 | if (cookiesToSend.at(i).value() != sent.at(i).value()) { |
562 | ok = false; |
563 | break; |
564 | } |
565 | } |
566 | if (!ok) { |
567 | QNetworkRequest r(sentUrl); |
568 | r.setHeader(header: QNetworkRequest::CookieHeader, value: QVariant::fromValue(value: cookiesToSend)); |
569 | QString actual = QString::fromUtf8(str: r.rawHeader(headerName: "Cookie" )); |
570 | r.setHeader(header: QNetworkRequest::CookieHeader, value: QVariant::fromValue(value: sent)); |
571 | QString expected = QString::fromUtf8(str: r.rawHeader(headerName: "Cookie" )); |
572 | |
573 | QVERIFY2(ok, qPrintable(QString("Expected: %1\nActual: %2" ).arg(expected).arg(actual))); |
574 | } |
575 | } |
576 | |
577 | QTEST_MAIN(tst_QNetworkCookieJar) |
578 | #include "tst_qnetworkcookiejar.moc" |
579 | |
580 | |