OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <ostream> |
10 | 10 |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
13 #include "base/scoped_native_library.h" | 13 #include "base/scoped_native_library.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/strings/sys_string_conversions.h" | |
18 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
19 #include "base/sys_byteorder.h" | 18 #include "base/sys_byteorder.h" |
20 #include "base/time/time.h" | 19 #include "base/time/time.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "url/gurl.h" | 21 #include "url/gurl.h" |
23 | 22 |
24 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
25 #include <iphlpapi.h> | 24 #include <iphlpapi.h> |
26 #include <objbase.h> | 25 #include <objbase.h> |
27 #include "base/win/windows_version.h" | 26 #include "base/win/windows_version.h" |
28 #elif !defined(OS_ANDROID) | 27 #elif !defined(OS_ANDROID) |
29 #include <net/if.h> | 28 #include <net/if.h> |
30 #endif // OS_WIN | 29 #endif // OS_WIN |
31 | 30 |
32 using base::ASCIIToUTF16; | 31 using base::ASCIIToUTF16; |
33 using base::WideToUTF16; | 32 using base::WideToUTF16; |
34 | 33 |
35 namespace net { | 34 namespace net { |
36 | 35 |
37 namespace { | 36 namespace { |
38 | 37 |
39 static const size_t kNpos = base::string16::npos; | |
40 | |
41 struct HeaderCase { | 38 struct HeaderCase { |
42 const char* header_name; | 39 const char* header_name; |
43 const char* expected; | 40 const char* expected; |
44 }; | 41 }; |
45 | 42 |
46 struct HeaderParamCase { | |
47 const char* header_name; | |
48 const char* param_name; | |
49 const char* expected; | |
50 }; | |
51 | |
52 const char* kLanguages[] = { | |
53 "", "en", "zh-CN", "ja", "ko", | |
54 "he", "ar", "ru", "el", "fr", | |
55 "de", "pt", "sv", "th", "hi", | |
56 "de,en", "el,en", "zh-TW,en", "ko,ja", "he,ru,en", | |
57 "zh,ru,en" | |
58 }; | |
59 | |
60 struct IDNTestCase { | |
61 const char* input; | |
62 const wchar_t* unicode_output; | |
63 const bool unicode_allowed[arraysize(kLanguages)]; | |
64 }; | |
65 | |
66 // TODO(jungshik) This is just a random sample of languages and is far | |
67 // from exhaustive. We may have to generate all the combinations | |
68 // of languages (powerset of a set of all the languages). | |
69 const IDNTestCase idn_cases[] = { | |
70 // No IDN | |
71 {"www.google.com", L"www.google.com", | |
72 {true, true, true, true, true, | |
73 true, true, true, true, true, | |
74 true, true, true, true, true, | |
75 true, true, true, true, true, | |
76 true}}, | |
77 {"www.google.com.", L"www.google.com.", | |
78 {true, true, true, true, true, | |
79 true, true, true, true, true, | |
80 true, true, true, true, true, | |
81 true, true, true, true, true, | |
82 true}}, | |
83 {".", L".", | |
84 {true, true, true, true, true, | |
85 true, true, true, true, true, | |
86 true, true, true, true, true, | |
87 true, true, true, true, true, | |
88 true}}, | |
89 {"", L"", | |
90 {true, true, true, true, true, | |
91 true, true, true, true, true, | |
92 true, true, true, true, true, | |
93 true, true, true, true, true, | |
94 true}}, | |
95 // IDN | |
96 // Hanzi (Traditional Chinese) | |
97 {"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", | |
98 {true, false, true, true, false, | |
99 false, false, false, false, false, | |
100 false, false, false, false, false, | |
101 false, false, true, true, false, | |
102 true}}, | |
103 // Hanzi ('video' in Simplified Chinese : will pass only in zh-CN,zh) | |
104 {"xn--cy2a840a.com", L"\x89c6\x9891.com", | |
105 {true, false, true, false, false, | |
106 false, false, false, false, false, | |
107 false, false, false, false, false, | |
108 false, false, false, false, false, | |
109 true}}, | |
110 // Hanzi + '123' | |
111 {"www.xn--123-p18d.com", L"www.\x4e00" L"123.com", | |
112 {true, false, true, true, false, | |
113 false, false, false, false, false, | |
114 false, false, false, false, false, | |
115 false, false, true, true, false, | |
116 true}}, | |
117 // Hanzi + Latin : U+56FD is simplified and is regarded | |
118 // as not supported in zh-TW. | |
119 {"www.xn--hello-9n1hm04c.com", L"www.hello\x4e2d\x56fd.com", | |
120 {false, false, true, true, false, | |
121 false, false, false, false, false, | |
122 false, false, false, false, false, | |
123 false, false, false, true, false, | |
124 true}}, | |
125 // Kanji + Kana (Japanese) | |
126 {"xn--l8jvb1ey91xtjb.jp", L"\x671d\x65e5\x3042\x3055\x3072.jp", | |
127 {true, false, false, true, false, | |
128 false, false, false, false, false, | |
129 false, false, false, false, false, | |
130 false, false, false, true, false, | |
131 false}}, | |
132 // Katakana including U+30FC | |
133 {"xn--tckm4i2e.jp", L"\x30b3\x30de\x30fc\x30b9.jp", | |
134 {true, false, false, true, false, | |
135 false, false, false, false, false, | |
136 false, false, false, false, false, | |
137 false, false, false, true, false, | |
138 }}, | |
139 {"xn--3ck7a7g.jp", L"\u30ce\u30f3\u30bd.jp", | |
140 {true, false, false, true, false, | |
141 false, false, false, false, false, | |
142 false, false, false, false, false, | |
143 false, false, false, true, false, | |
144 }}, | |
145 // Katakana + Latin (Japanese) | |
146 // TODO(jungshik): Change 'false' in the first element to 'true' | |
147 // after upgrading to ICU 4.2.1 to use new uspoof_* APIs instead | |
148 // of our IsIDNComponentInSingleScript(). | |
149 {"xn--e-efusa1mzf.jp", L"e\x30b3\x30de\x30fc\x30b9.jp", | |
150 {false, false, false, true, false, | |
151 false, false, false, false, false, | |
152 false, false, false, false, false, | |
153 false, false, false, true, false, | |
154 }}, | |
155 {"xn--3bkxe.jp", L"\x30c8\x309a.jp", | |
156 {false, false, false, true, false, | |
157 false, false, false, false, false, | |
158 false, false, false, false, false, | |
159 false, false, false, true, false, | |
160 }}, | |
161 // Hangul (Korean) | |
162 {"www.xn--or3b17p6jjc.kr", L"www.\xc804\xc790\xc815\xbd80.kr", | |
163 {true, false, false, false, true, | |
164 false, false, false, false, false, | |
165 false, false, false, false, false, | |
166 false, false, false, true, false, | |
167 false}}, | |
168 // b<u-umlaut>cher (German) | |
169 {"xn--bcher-kva.de", L"b\x00fc" L"cher.de", | |
170 {true, false, false, false, false, | |
171 false, false, false, false, true, | |
172 true, false, false, false, false, | |
173 true, false, false, false, false, | |
174 false}}, | |
175 // a with diaeresis | |
176 {"www.xn--frgbolaget-q5a.se", L"www.f\x00e4rgbolaget.se", | |
177 {true, false, false, false, false, | |
178 false, false, false, false, false, | |
179 true, false, true, false, false, | |
180 true, false, false, false, false, | |
181 false}}, | |
182 // c-cedilla (French) | |
183 {"www.xn--alliancefranaise-npb.fr", L"www.alliancefran\x00e7" L"aise.fr", | |
184 {true, false, false, false, false, | |
185 false, false, false, false, true, | |
186 false, true, false, false, false, | |
187 false, false, false, false, false, | |
188 false}}, | |
189 // caf'e with acute accent' (French) | |
190 {"xn--caf-dma.fr", L"caf\x00e9.fr", | |
191 {true, false, false, false, false, | |
192 false, false, false, false, true, | |
193 false, true, true, false, false, | |
194 false, false, false, false, false, | |
195 false}}, | |
196 // c-cedillla and a with tilde (Portuguese) | |
197 {"xn--poema-9qae5a.com.br", L"p\x00e3oema\x00e7\x00e3.com.br", | |
198 {true, false, false, false, false, | |
199 false, false, false, false, false, | |
200 false, true, false, false, false, | |
201 false, false, false, false, false, | |
202 false}}, | |
203 // s with caron | |
204 {"xn--achy-f6a.com", L"\x0161" L"achy.com", | |
205 {true, false, false, false, false, | |
206 false, false, false, false, false, | |
207 false, false, false, false, false, | |
208 false, false, false, false, false, | |
209 false}}, | |
210 // TODO(jungshik) : Add examples with Cyrillic letters | |
211 // only used in some languages written in Cyrillic. | |
212 // Eutopia (Greek) | |
213 {"xn--kxae4bafwg.gr", L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1.gr", | |
214 {true, false, false, false, false, | |
215 false, false, false, true, false, | |
216 false, false, false, false, false, | |
217 false, true, false, false, false, | |
218 false}}, | |
219 // Eutopia + 123 (Greek) | |
220 {"xn---123-pldm0haj2bk.gr", | |
221 L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1-123.gr", | |
222 {true, false, false, false, false, | |
223 false, false, false, true, false, | |
224 false, false, false, false, false, | |
225 false, true, false, false, false, | |
226 false}}, | |
227 // Cyrillic (Russian) | |
228 {"xn--n1aeec9b.ru", L"\x0442\x043e\x0440\x0442\x044b.ru", | |
229 {true, false, false, false, false, | |
230 false, false, true, false, false, | |
231 false, false, false, false, false, | |
232 false, false, false, false, true, | |
233 true}}, | |
234 // Cyrillic + 123 (Russian) | |
235 {"xn---123-45dmmc5f.ru", L"\x0442\x043e\x0440\x0442\x044b-123.ru", | |
236 {true, false, false, false, false, | |
237 false, false, true, false, false, | |
238 false, false, false, false, false, | |
239 false, false, false, false, true, | |
240 true}}, | |
241 // Arabic | |
242 {"xn--mgba1fmg.ar", L"\x0627\x0641\x0644\x0627\x0645.ar", | |
243 {true, false, false, false, false, | |
244 false, true, false, false, false, | |
245 false, false, false, false, false, | |
246 false, false, false, false, false, | |
247 false}}, | |
248 // Hebrew | |
249 {"xn--4dbib.he", L"\x05d5\x05d0\x05d4.he", | |
250 {true, false, false, false, false, | |
251 true, false, false, false, false, | |
252 false, false, false, false, false, | |
253 false, false, false, false, true, | |
254 false}}, | |
255 // Thai | |
256 {"xn--12c2cc4ag3b4ccu.th", | |
257 L"\x0e2a\x0e32\x0e22\x0e01\x0e32\x0e23\x0e1a\x0e34\x0e19.th", | |
258 {true, false, false, false, false, | |
259 false, false, false, false, false, | |
260 false, false, false, true, false, | |
261 false, false, false, false, false, | |
262 false}}, | |
263 // Devangari (Hindi) | |
264 {"www.xn--l1b6a9e1b7c.in", L"www.\x0905\x0915\x094b\x0932\x093e.in", | |
265 {true, false, false, false, false, | |
266 false, false, false, false, false, | |
267 false, false, false, false, true, | |
268 false, false, false, false, false, | |
269 false}}, | |
270 // Invalid IDN | |
271 {"xn--hello?world.com", NULL, | |
272 {false, false, false, false, false, | |
273 false, false, false, false, false, | |
274 false, false, false, false, false, | |
275 false, false, false, false, false, | |
276 false}}, | |
277 // Unsafe IDNs | |
278 // "payp<alpha>l.com" | |
279 {"www.xn--paypl-g9d.com", L"payp\x03b1l.com", | |
280 {false, false, false, false, false, | |
281 false, false, false, false, false, | |
282 false, false, false, false, false, | |
283 false, false, false, false, false, | |
284 false}}, | |
285 // google.gr with Greek omicron and epsilon | |
286 {"xn--ggl-6xc1ca.gr", L"g\x03bf\x03bfgl\x03b5.gr", | |
287 {false, false, false, false, false, | |
288 false, false, false, false, false, | |
289 false, false, false, false, false, | |
290 false, false, false, false, false, | |
291 false}}, | |
292 // google.ru with Cyrillic o | |
293 {"xn--ggl-tdd6ba.ru", L"g\x043e\x043egl\x0435.ru", | |
294 {false, false, false, false, false, | |
295 false, false, false, false, false, | |
296 false, false, false, false, false, | |
297 false, false, false, false, false, | |
298 false}}, | |
299 // h<e with acute>llo<China in Han>.cn | |
300 {"xn--hllo-bpa7979ih5m.cn", L"h\x00e9llo\x4e2d\x56fd.cn", | |
301 {false, false, false, false, false, | |
302 false, false, false, false, false, | |
303 false, false, false, false, false, | |
304 false, false, false, false, false, | |
305 false}}, | |
306 // <Greek rho><Cyrillic a><Cyrillic u>.ru | |
307 {"xn--2xa6t2b.ru", L"\x03c1\x0430\x0443.ru", | |
308 {false, false, false, false, false, | |
309 false, false, false, false, false, | |
310 false, false, false, false, false, | |
311 false, false, false, false, false, | |
312 false}}, | |
313 // One that's really long that will force a buffer realloc | |
314 {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" | |
315 "aaaaaaa", | |
316 L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" | |
317 L"aaaaaaaa", | |
318 {true, true, true, true, true, | |
319 true, true, true, true, true, | |
320 true, true, true, true, true, | |
321 true, true, true, true, true, | |
322 true}}, | |
323 // Test cases for characters we blacklisted although allowed in IDN. | |
324 // Embedded spaces will be turned to %20 in the display. | |
325 // TODO(jungshik): We need to have more cases. This is a typical | |
326 // data-driven trap. The following test cases need to be separated | |
327 // and tested only for a couple of languages. | |
328 {"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr", | |
329 {false, false, false, false, false, | |
330 false, false, false, false, false, | |
331 false, false, false, false, false, | |
332 false, false, false, false, false, | |
333 false}}, | |
334 {"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com", | |
335 {false, false, false, false, false, | |
336 false, false, false, false, false, | |
337 false, false, false, false, false, | |
338 false, false, false, false, false, | |
339 }}, | |
340 {"google.xn--comabc-k8d", L"google.com\x0338" L"abc", | |
341 {false, false, false, false, false, | |
342 false, false, false, false, false, | |
343 false, false, false, false, false, | |
344 false, false, false, false, false, | |
345 }}, | |
346 {"google.xn--com-oh4ba.evil.jp", L"google.com\x309a\x309a.evil.jp", | |
347 {false, false, false, false, false, | |
348 false, false, false, false, false, | |
349 false, false, false, false, false, | |
350 false, false, false, false, false, | |
351 }}, | |
352 {"google.xn--comevil-v04f.jp", L"google.com\x30ce" L"evil.jp", | |
353 {false, false, false, false, false, | |
354 false, false, false, false, false, | |
355 false, false, false, false, false, | |
356 false, false, false, false, false, | |
357 }}, | |
358 #if 0 | |
359 // These two cases are special. We need a separate test. | |
360 // U+3000 and U+3002 are normalized to ASCII space and dot. | |
361 {"xn-- -kq6ay5z.cn", L"\x4e2d\x56fd\x3000.cn", | |
362 {false, false, true, false, false, | |
363 false, false, false, false, false, | |
364 false, false, false, false, false, | |
365 false, false, true, false, false, | |
366 true}}, | |
367 {"xn--fiqs8s.cn", L"\x4e2d\x56fd\x3002" L"cn", | |
368 {false, false, true, false, false, | |
369 false, false, false, false, false, | |
370 false, false, false, false, false, | |
371 false, false, true, false, false, | |
372 true}}, | |
373 #endif | |
374 }; | |
375 | |
376 struct AdjustOffsetCase { | |
377 size_t input_offset; | |
378 size_t output_offset; | |
379 }; | |
380 | |
381 struct CompliantHostCase { | 43 struct CompliantHostCase { |
382 const char* host; | 44 const char* host; |
383 const char* desired_tld; | 45 const char* desired_tld; |
384 bool expected_output; | 46 bool expected_output; |
385 }; | 47 }; |
386 | 48 |
387 struct UrlTestData { | |
388 const char* description; | |
389 const char* input; | |
390 const char* languages; | |
391 FormatUrlTypes format_types; | |
392 UnescapeRule::Type escape_rules; | |
393 const wchar_t* output; // Use |wchar_t| to handle Unicode constants easily. | |
394 size_t prefix_len; | |
395 }; | |
396 | |
397 // Fills in sockaddr for the given 32-bit address (IPv4.) | 49 // Fills in sockaddr for the given 32-bit address (IPv4.) |
398 // |bytes| should be an array of length 4. | 50 // |bytes| should be an array of length 4. |
399 void MakeIPv4Address(const uint8* bytes, int port, SockaddrStorage* storage) { | 51 void MakeIPv4Address(const uint8* bytes, int port, SockaddrStorage* storage) { |
400 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); | 52 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); |
401 storage->addr_len = sizeof(struct sockaddr_in); | 53 storage->addr_len = sizeof(struct sockaddr_in); |
402 struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(storage->addr); | 54 struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(storage->addr); |
403 addr4->sin_port = base::HostToNet16(port); | 55 addr4->sin_port = base::HostToNet16(port); |
404 addr4->sin_family = AF_INET; | 56 addr4->sin_family = AF_INET; |
405 memcpy(&addr4->sin_addr, bytes, 4); | 57 memcpy(&addr4->sin_addr, bytes, 4); |
406 } | 58 } |
407 | 59 |
408 // Fills in sockaddr for the given 128-bit address (IPv6.) | 60 // Fills in sockaddr for the given 128-bit address (IPv6.) |
409 // |bytes| should be an array of length 16. | 61 // |bytes| should be an array of length 16. |
410 void MakeIPv6Address(const uint8* bytes, int port, SockaddrStorage* storage) { | 62 void MakeIPv6Address(const uint8* bytes, int port, SockaddrStorage* storage) { |
411 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); | 63 memset(&storage->addr_storage, 0, sizeof(storage->addr_storage)); |
412 storage->addr_len = sizeof(struct sockaddr_in6); | 64 storage->addr_len = sizeof(struct sockaddr_in6); |
413 struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(storage->addr); | 65 struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(storage->addr); |
414 addr6->sin6_port = base::HostToNet16(port); | 66 addr6->sin6_port = base::HostToNet16(port); |
415 addr6->sin6_family = AF_INET6; | 67 addr6->sin6_family = AF_INET6; |
416 memcpy(&addr6->sin6_addr, bytes, 16); | 68 memcpy(&addr6->sin6_addr, bytes, 16); |
417 } | 69 } |
418 | 70 |
419 // A helper for IDN*{Fast,Slow}. | |
420 // Append "::<language list>" to |expected| and |actual| to make it | |
421 // easy to tell which sub-case fails without debugging. | |
422 void AppendLanguagesToOutputs(const char* languages, | |
423 base::string16* expected, | |
424 base::string16* actual) { | |
425 base::string16 to_append = ASCIIToUTF16("::") + ASCIIToUTF16(languages); | |
426 expected->append(to_append); | |
427 actual->append(to_append); | |
428 } | |
429 | |
430 // A pair of helpers for the FormatUrlWithOffsets() test. | |
431 void VerboseExpect(size_t expected, | |
432 size_t actual, | |
433 const std::string& original_url, | |
434 size_t position, | |
435 const base::string16& formatted_url) { | |
436 EXPECT_EQ(expected, actual) << "Original URL: " << original_url | |
437 << " (at char " << position << ")\nFormatted URL: " << formatted_url; | |
438 } | |
439 | |
440 void CheckAdjustedOffsets(const std::string& url_string, | |
441 const std::string& languages, | |
442 FormatUrlTypes format_types, | |
443 UnescapeRule::Type unescape_rules, | |
444 const size_t* output_offsets) { | |
445 GURL url(url_string); | |
446 size_t url_length = url_string.length(); | |
447 std::vector<size_t> offsets; | |
448 for (size_t i = 0; i <= url_length + 1; ++i) | |
449 offsets.push_back(i); | |
450 offsets.push_back(500000); // Something larger than any input length. | |
451 offsets.push_back(std::string::npos); | |
452 base::string16 formatted_url = FormatUrlWithOffsets(url, languages, | |
453 format_types, unescape_rules, NULL, NULL, &offsets); | |
454 for (size_t i = 0; i < url_length; ++i) | |
455 VerboseExpect(output_offsets[i], offsets[i], url_string, i, formatted_url); | |
456 VerboseExpect(formatted_url.length(), offsets[url_length], url_string, | |
457 url_length, formatted_url); | |
458 VerboseExpect(base::string16::npos, offsets[url_length + 1], url_string, | |
459 500000, formatted_url); | |
460 VerboseExpect(base::string16::npos, offsets[url_length + 2], url_string, | |
461 std::string::npos, formatted_url); | |
462 } | |
463 | |
464 // Helper to strignize an IP number (used to define expectations). | 71 // Helper to strignize an IP number (used to define expectations). |
465 std::string DumpIPNumber(const IPAddressNumber& v) { | 72 std::string DumpIPNumber(const IPAddressNumber& v) { |
466 std::string out; | 73 std::string out; |
467 for (size_t i = 0; i < v.size(); ++i) { | 74 for (size_t i = 0; i < v.size(); ++i) { |
468 if (i != 0) | 75 if (i != 0) |
469 out.append(","); | 76 out.append(","); |
470 out.append(base::IntToString(static_cast<int>(v[i]))); | 77 out.append(base::IntToString(static_cast<int>(v[i]))); |
471 } | 78 } |
472 return out; | 79 return out; |
473 } | 80 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 EXPECT_EQ(result, tests[i].expected); | 191 EXPECT_EQ(result, tests[i].expected); |
585 } | 192 } |
586 | 193 |
587 // Test again with empty headers. | 194 // Test again with empty headers. |
588 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 195 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
589 std::string result = GetSpecificHeader(std::string(), tests[i].header_name); | 196 std::string result = GetSpecificHeader(std::string(), tests[i].header_name); |
590 EXPECT_EQ(result, std::string()); | 197 EXPECT_EQ(result, std::string()); |
591 } | 198 } |
592 } | 199 } |
593 | 200 |
594 TEST(NetUtilTest, IDNToUnicodeFast) { | |
595 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) { | |
596 for (size_t j = 0; j < arraysize(kLanguages); j++) { | |
597 // ja || zh-TW,en || ko,ja -> IDNToUnicodeSlow | |
598 if (j == 3 || j == 17 || j == 18) | |
599 continue; | |
600 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); | |
601 base::string16 expected(idn_cases[i].unicode_allowed[j] ? | |
602 WideToUTF16(idn_cases[i].unicode_output) : | |
603 ASCIIToUTF16(idn_cases[i].input)); | |
604 AppendLanguagesToOutputs(kLanguages[j], &expected, &output); | |
605 EXPECT_EQ(expected, output); | |
606 } | |
607 } | |
608 } | |
609 | |
610 TEST(NetUtilTest, IDNToUnicodeSlow) { | |
611 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(idn_cases); i++) { | |
612 for (size_t j = 0; j < arraysize(kLanguages); j++) { | |
613 // !(ja || zh-TW,en || ko,ja) -> IDNToUnicodeFast | |
614 if (!(j == 3 || j == 17 || j == 18)) | |
615 continue; | |
616 base::string16 output(IDNToUnicode(idn_cases[i].input, kLanguages[j])); | |
617 base::string16 expected(idn_cases[i].unicode_allowed[j] ? | |
618 WideToUTF16(idn_cases[i].unicode_output) : | |
619 ASCIIToUTF16(idn_cases[i].input)); | |
620 AppendLanguagesToOutputs(kLanguages[j], &expected, &output); | |
621 EXPECT_EQ(expected, output); | |
622 } | |
623 } | |
624 } | |
625 | |
626 TEST(NetUtilTest, CompliantHost) { | 201 TEST(NetUtilTest, CompliantHost) { |
627 const CompliantHostCase compliant_host_cases[] = { | 202 const CompliantHostCase compliant_host_cases[] = { |
628 {"", "", false}, | 203 {"", "", false}, |
629 {"a", "", true}, | 204 {"a", "", true}, |
630 {"-", "", false}, | 205 {"-", "", false}, |
631 {".", "", false}, | 206 {".", "", false}, |
632 {"9", "", true}, | 207 {"9", "", true}, |
633 {"9a", "", true}, | 208 {"9a", "", true}, |
634 {"a.", "", true}, | 209 {"a.", "", true}, |
635 {"a.a", "", true}, | 210 {"a.a", "", true}, |
(...skipping 14 matching lines...) Expand all Loading... |
650 {"1.2.3.4.5.", "", true}, | 225 {"1.2.3.4.5.", "", true}, |
651 }; | 226 }; |
652 | 227 |
653 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(compliant_host_cases); ++i) { | 228 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(compliant_host_cases); ++i) { |
654 EXPECT_EQ(compliant_host_cases[i].expected_output, | 229 EXPECT_EQ(compliant_host_cases[i].expected_output, |
655 IsCanonicalizedHostCompliant(compliant_host_cases[i].host, | 230 IsCanonicalizedHostCompliant(compliant_host_cases[i].host, |
656 compliant_host_cases[i].desired_tld)); | 231 compliant_host_cases[i].desired_tld)); |
657 } | 232 } |
658 } | 233 } |
659 | 234 |
660 TEST(NetUtilTest, StripWWW) { | |
661 EXPECT_EQ(base::string16(), StripWWW(base::string16())); | |
662 EXPECT_EQ(base::string16(), StripWWW(ASCIIToUTF16("www."))); | |
663 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("www.blah"))); | |
664 EXPECT_EQ(ASCIIToUTF16("blah"), StripWWW(ASCIIToUTF16("blah"))); | |
665 } | |
666 | |
667 // This is currently a windows specific function. | |
668 #if defined(OS_WIN) | |
669 namespace { | |
670 | |
671 struct GetDirectoryListingEntryCase { | |
672 const wchar_t* name; | |
673 const char* raw_bytes; | |
674 bool is_dir; | |
675 int64 filesize; | |
676 base::Time time; | |
677 const char* expected; | |
678 }; | |
679 | |
680 } // namespace | |
681 TEST(NetUtilTest, GetDirectoryListingEntry) { | |
682 const GetDirectoryListingEntryCase test_cases[] = { | |
683 {L"Foo", | |
684 "", | |
685 false, | |
686 10000, | |
687 base::Time(), | |
688 "<script>addRow(\"Foo\",\"Foo\",0,\"9.8 kB\",\"\");</script>\n"}, | |
689 {L"quo\"tes", | |
690 "", | |
691 false, | |
692 10000, | |
693 base::Time(), | |
694 "<script>addRow(\"quo\\\"tes\",\"quo%22tes\",0,\"9.8 kB\",\"\");</script>" | |
695 "\n"}, | |
696 {L"quo\"tes", | |
697 "quo\"tes", | |
698 false, | |
699 10000, | |
700 base::Time(), | |
701 "<script>addRow(\"quo\\\"tes\",\"quo%22tes\",0,\"9.8 kB\",\"\");</script>" | |
702 "\n"}, | |
703 // U+D55C0 U+AE00. raw_bytes is empty (either a local file with | |
704 // UTF-8/UTF-16 encoding or a remote file on an ftp server using UTF-8 | |
705 {L"\xD55C\xAE00.txt", | |
706 "", | |
707 false, | |
708 10000, | |
709 base::Time(), | |
710 "<script>addRow(\"\xED\x95\x9C\xEA\xB8\x80.txt\"," | |
711 "\"%ED%95%9C%EA%B8%80.txt\",0,\"9.8 kB\",\"\");</script>\n"}, | |
712 // U+D55C0 U+AE00. raw_bytes is the corresponding EUC-KR sequence: | |
713 // a local or remote file in EUC-KR. | |
714 {L"\xD55C\xAE00.txt", | |
715 "\xC7\xD1\xB1\xDB.txt", | |
716 false, | |
717 10000, | |
718 base::Time(), | |
719 "<script>addRow(\"\xED\x95\x9C\xEA\xB8\x80.txt\",\"%C7%D1%B1%DB.txt\"" | |
720 ",0,\"9.8 kB\",\"\");</script>\n"}, | |
721 }; | |
722 | |
723 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { | |
724 const std::string results = GetDirectoryListingEntry( | |
725 WideToUTF16(test_cases[i].name), | |
726 test_cases[i].raw_bytes, | |
727 test_cases[i].is_dir, | |
728 test_cases[i].filesize, | |
729 test_cases[i].time); | |
730 EXPECT_EQ(test_cases[i].expected, results); | |
731 } | |
732 } | |
733 | |
734 #endif | |
735 | |
736 TEST(NetUtilTest, ParseHostAndPort) { | 235 TEST(NetUtilTest, ParseHostAndPort) { |
737 const struct { | 236 const struct { |
738 const char* input; | 237 const char* input; |
739 bool success; | 238 bool success; |
740 const char* expected_host; | 239 const char* expected_host; |
741 int expected_port; | 240 int expected_port; |
742 } tests[] = { | 241 } tests[] = { |
743 // Valid inputs: | 242 // Valid inputs: |
744 {"foo:10", true, "foo", 10}, | 243 {"foo:10", true, "foo", 10}, |
745 {"foo", true, "foo", -1}, | 244 {"foo", true, "foo", -1}, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 } | 398 } |
900 | 399 |
901 TEST(NetUtilTest, GetHostName) { | 400 TEST(NetUtilTest, GetHostName) { |
902 // We can't check the result of GetHostName() directly, since the result | 401 // We can't check the result of GetHostName() directly, since the result |
903 // will differ across machines. Our goal here is to simply exercise the | 402 // will differ across machines. Our goal here is to simply exercise the |
904 // code path, and check that things "look about right". | 403 // code path, and check that things "look about right". |
905 std::string hostname = GetHostName(); | 404 std::string hostname = GetHostName(); |
906 EXPECT_FALSE(hostname.empty()); | 405 EXPECT_FALSE(hostname.empty()); |
907 } | 406 } |
908 | 407 |
909 TEST(NetUtilTest, FormatUrl) { | |
910 FormatUrlTypes default_format_type = kFormatUrlOmitUsernamePassword; | |
911 const UrlTestData tests[] = { | |
912 {"Empty URL", "", "", default_format_type, UnescapeRule::NORMAL, L"", 0}, | |
913 | |
914 {"Simple URL", | |
915 "http://www.google.com/", "", default_format_type, UnescapeRule::NORMAL, | |
916 L"http://www.google.com/", 7}, | |
917 | |
918 {"With a port number and a reference", | |
919 "http://www.google.com:8080/#\xE3\x82\xB0", "", default_format_type, | |
920 UnescapeRule::NORMAL, | |
921 L"http://www.google.com:8080/#\x30B0", 7}, | |
922 | |
923 // -------- IDN tests -------- | |
924 {"Japanese IDN with ja", | |
925 "http://xn--l8jvb1ey91xtjb.jp", "ja", default_format_type, | |
926 UnescapeRule::NORMAL, L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, | |
927 | |
928 {"Japanese IDN with en", | |
929 "http://xn--l8jvb1ey91xtjb.jp", "en", default_format_type, | |
930 UnescapeRule::NORMAL, L"http://xn--l8jvb1ey91xtjb.jp/", 7}, | |
931 | |
932 {"Japanese IDN without any languages", | |
933 "http://xn--l8jvb1ey91xtjb.jp", "", default_format_type, | |
934 UnescapeRule::NORMAL, | |
935 // Single script is safe for empty languages. | |
936 L"http://\x671d\x65e5\x3042\x3055\x3072.jp/", 7}, | |
937 | |
938 {"mailto: with Japanese IDN", | |
939 "mailto:foo@xn--l8jvb1ey91xtjb.jp", "ja", default_format_type, | |
940 UnescapeRule::NORMAL, | |
941 // GURL doesn't assume an email address's domain part as a host name. | |
942 L"mailto:foo@xn--l8jvb1ey91xtjb.jp", 7}, | |
943 | |
944 {"file: with Japanese IDN", | |
945 "file://xn--l8jvb1ey91xtjb.jp/config.sys", "ja", default_format_type, | |
946 UnescapeRule::NORMAL, | |
947 L"file://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 7}, | |
948 | |
949 {"ftp: with Japanese IDN", | |
950 "ftp://xn--l8jvb1ey91xtjb.jp/config.sys", "ja", default_format_type, | |
951 UnescapeRule::NORMAL, | |
952 L"ftp://\x671d\x65e5\x3042\x3055\x3072.jp/config.sys", 6}, | |
953 | |
954 // -------- omit_username_password flag tests -------- | |
955 {"With username and password, omit_username_password=false", | |
956 "http://user:passwd@example.com/foo", "", | |
957 kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
958 L"http://user:passwd@example.com/foo", 19}, | |
959 | |
960 {"With username and password, omit_username_password=true", | |
961 "http://user:passwd@example.com/foo", "", default_format_type, | |
962 UnescapeRule::NORMAL, L"http://example.com/foo", 7}, | |
963 | |
964 {"With username and no password", | |
965 "http://user@example.com/foo", "", default_format_type, | |
966 UnescapeRule::NORMAL, L"http://example.com/foo", 7}, | |
967 | |
968 {"Just '@' without username and password", | |
969 "http://@example.com/foo", "", default_format_type, UnescapeRule::NORMAL, | |
970 L"http://example.com/foo", 7}, | |
971 | |
972 // GURL doesn't think local-part of an email address is username for URL. | |
973 {"mailto:, omit_username_password=true", | |
974 "mailto:foo@example.com", "", default_format_type, UnescapeRule::NORMAL, | |
975 L"mailto:foo@example.com", 7}, | |
976 | |
977 // -------- unescape flag tests -------- | |
978 {"Do not unescape", | |
979 "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" | |
980 "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" | |
981 "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", "en", default_format_type, | |
982 UnescapeRule::NONE, | |
983 // GURL parses %-encoded hostnames into Punycode. | |
984 L"http://xn--qcka1pmc.jp/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" | |
985 L"?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", 7}, | |
986 | |
987 {"Unescape normally", | |
988 "http://%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB.jp/" | |
989 "%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB" | |
990 "?q=%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", "en", default_format_type, | |
991 UnescapeRule::NORMAL, | |
992 L"http://xn--qcka1pmc.jp/\x30B0\x30FC\x30B0\x30EB" | |
993 L"?q=\x30B0\x30FC\x30B0\x30EB", 7}, | |
994 | |
995 {"Unescape normally with BiDi control character", | |
996 "http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", "en", default_format_type, | |
997 UnescapeRule::NORMAL, L"http://example.com/%E2%80%AEabc?q=%E2%80%8Fxy", 7}, | |
998 | |
999 {"Unescape normally including unescape spaces", | |
1000 "http://www.google.com/search?q=Hello%20World", "en", default_format_type, | |
1001 UnescapeRule::SPACES, L"http://www.google.com/search?q=Hello World", 7}, | |
1002 | |
1003 /* | |
1004 {"unescape=true with some special characters", | |
1005 "http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", "", | |
1006 kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
1007 L"http://user%3A:%40passwd@example.com/foo%3Fbar?q=b%26z", 25}, | |
1008 */ | |
1009 // Disabled: the resultant URL becomes "...user%253A:%2540passwd...". | |
1010 | |
1011 // -------- omit http: -------- | |
1012 {"omit http with user name", | |
1013 "http://user@example.com/foo", "", kFormatUrlOmitAll, | |
1014 UnescapeRule::NORMAL, L"example.com/foo", 0}, | |
1015 | |
1016 {"omit http", | |
1017 "http://www.google.com/", "en", kFormatUrlOmitHTTP, | |
1018 UnescapeRule::NORMAL, L"www.google.com/", | |
1019 0}, | |
1020 | |
1021 {"omit http with https", | |
1022 "https://www.google.com/", "en", kFormatUrlOmitHTTP, | |
1023 UnescapeRule::NORMAL, L"https://www.google.com/", | |
1024 8}, | |
1025 | |
1026 {"omit http starts with ftp.", | |
1027 "http://ftp.google.com/", "en", kFormatUrlOmitHTTP, | |
1028 UnescapeRule::NORMAL, L"http://ftp.google.com/", | |
1029 7}, | |
1030 | |
1031 // -------- omit trailing slash on bare hostname -------- | |
1032 {"omit slash when it's the entire path", | |
1033 "http://www.google.com/", "en", | |
1034 kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, | |
1035 L"http://www.google.com", 7}, | |
1036 {"omit slash when there's a ref", | |
1037 "http://www.google.com/#ref", "en", | |
1038 kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, | |
1039 L"http://www.google.com/#ref", 7}, | |
1040 {"omit slash when there's a query", | |
1041 "http://www.google.com/?", "en", | |
1042 kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, | |
1043 L"http://www.google.com/?", 7}, | |
1044 {"omit slash when it's not the entire path", | |
1045 "http://www.google.com/foo", "en", | |
1046 kFormatUrlOmitTrailingSlashOnBareHostname, UnescapeRule::NORMAL, | |
1047 L"http://www.google.com/foo", 7}, | |
1048 {"omit slash for nonstandard URLs", | |
1049 "data:/", "en", kFormatUrlOmitTrailingSlashOnBareHostname, | |
1050 UnescapeRule::NORMAL, L"data:/", 5}, | |
1051 {"omit slash for file URLs", | |
1052 "file:///", "en", kFormatUrlOmitTrailingSlashOnBareHostname, | |
1053 UnescapeRule::NORMAL, L"file:///", 7}, | |
1054 | |
1055 // -------- view-source: -------- | |
1056 {"view-source", | |
1057 "view-source:http://xn--qcka1pmc.jp/", "ja", default_format_type, | |
1058 UnescapeRule::NORMAL, L"view-source:http://\x30B0\x30FC\x30B0\x30EB.jp/", | |
1059 19}, | |
1060 | |
1061 {"view-source of view-source", | |
1062 "view-source:view-source:http://xn--qcka1pmc.jp/", "ja", | |
1063 default_format_type, UnescapeRule::NORMAL, | |
1064 L"view-source:view-source:http://xn--qcka1pmc.jp/", 12}, | |
1065 | |
1066 // view-source should omit http and trailing slash where non-view-source | |
1067 // would. | |
1068 {"view-source omit http", | |
1069 "view-source:http://a.b/c", "en", kFormatUrlOmitAll, | |
1070 UnescapeRule::NORMAL, L"view-source:a.b/c", | |
1071 12}, | |
1072 {"view-source omit http starts with ftp.", | |
1073 "view-source:http://ftp.b/c", "en", kFormatUrlOmitAll, | |
1074 UnescapeRule::NORMAL, L"view-source:http://ftp.b/c", | |
1075 19}, | |
1076 {"view-source omit slash when it's the entire path", | |
1077 "view-source:http://a.b/", "en", kFormatUrlOmitAll, | |
1078 UnescapeRule::NORMAL, L"view-source:a.b", | |
1079 12}, | |
1080 }; | |
1081 | |
1082 for (size_t i = 0; i < arraysize(tests); ++i) { | |
1083 size_t prefix_len; | |
1084 base::string16 formatted = FormatUrl( | |
1085 GURL(tests[i].input), tests[i].languages, tests[i].format_types, | |
1086 tests[i].escape_rules, NULL, &prefix_len, NULL); | |
1087 EXPECT_EQ(WideToUTF16(tests[i].output), formatted) << tests[i].description; | |
1088 EXPECT_EQ(tests[i].prefix_len, prefix_len) << tests[i].description; | |
1089 } | |
1090 } | |
1091 | |
1092 TEST(NetUtilTest, FormatUrlParsed) { | |
1093 // No unescape case. | |
1094 url::Parsed parsed; | |
1095 base::string16 formatted = FormatUrl( | |
1096 GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" | |
1097 "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), | |
1098 "ja", kFormatUrlOmitNothing, UnescapeRule::NONE, &parsed, NULL, | |
1099 NULL); | |
1100 EXPECT_EQ(WideToUTF16( | |
1101 L"http://%E3%82%B0:%E3%83%BC@\x30B0\x30FC\x30B0\x30EB.jp:8080" | |
1102 L"/%E3%82%B0/?q=%E3%82%B0#\x30B0"), formatted); | |
1103 EXPECT_EQ(WideToUTF16(L"%E3%82%B0"), | |
1104 formatted.substr(parsed.username.begin, parsed.username.len)); | |
1105 EXPECT_EQ(WideToUTF16(L"%E3%83%BC"), | |
1106 formatted.substr(parsed.password.begin, parsed.password.len)); | |
1107 EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), | |
1108 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1109 EXPECT_EQ(WideToUTF16(L"8080"), | |
1110 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1111 EXPECT_EQ(WideToUTF16(L"/%E3%82%B0/"), | |
1112 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1113 EXPECT_EQ(WideToUTF16(L"q=%E3%82%B0"), | |
1114 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1115 EXPECT_EQ(WideToUTF16(L"\x30B0"), | |
1116 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1117 | |
1118 // Unescape case. | |
1119 formatted = FormatUrl( | |
1120 GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" | |
1121 "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), | |
1122 "ja", kFormatUrlOmitNothing, UnescapeRule::NORMAL, &parsed, NULL, | |
1123 NULL); | |
1124 EXPECT_EQ(WideToUTF16(L"http://\x30B0:\x30FC@\x30B0\x30FC\x30B0\x30EB.jp:8080" | |
1125 L"/\x30B0/?q=\x30B0#\x30B0"), formatted); | |
1126 EXPECT_EQ(WideToUTF16(L"\x30B0"), | |
1127 formatted.substr(parsed.username.begin, parsed.username.len)); | |
1128 EXPECT_EQ(WideToUTF16(L"\x30FC"), | |
1129 formatted.substr(parsed.password.begin, parsed.password.len)); | |
1130 EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), | |
1131 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1132 EXPECT_EQ(WideToUTF16(L"8080"), | |
1133 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1134 EXPECT_EQ(WideToUTF16(L"/\x30B0/"), | |
1135 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1136 EXPECT_EQ(WideToUTF16(L"q=\x30B0"), | |
1137 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1138 EXPECT_EQ(WideToUTF16(L"\x30B0"), | |
1139 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1140 | |
1141 // Omit_username_password + unescape case. | |
1142 formatted = FormatUrl( | |
1143 GURL("http://\xE3\x82\xB0:\xE3\x83\xBC@xn--qcka1pmc.jp:8080/" | |
1144 "%E3%82%B0/?q=%E3%82%B0#\xE3\x82\xB0"), | |
1145 "ja", kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, &parsed, | |
1146 NULL, NULL); | |
1147 EXPECT_EQ(WideToUTF16(L"http://\x30B0\x30FC\x30B0\x30EB.jp:8080" | |
1148 L"/\x30B0/?q=\x30B0#\x30B0"), formatted); | |
1149 EXPECT_FALSE(parsed.username.is_valid()); | |
1150 EXPECT_FALSE(parsed.password.is_valid()); | |
1151 EXPECT_EQ(WideToUTF16(L"\x30B0\x30FC\x30B0\x30EB.jp"), | |
1152 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1153 EXPECT_EQ(WideToUTF16(L"8080"), | |
1154 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1155 EXPECT_EQ(WideToUTF16(L"/\x30B0/"), | |
1156 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1157 EXPECT_EQ(WideToUTF16(L"q=\x30B0"), | |
1158 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1159 EXPECT_EQ(WideToUTF16(L"\x30B0"), | |
1160 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1161 | |
1162 // View-source case. | |
1163 formatted = | |
1164 FormatUrl(GURL("view-source:http://user:passwd@host:81/path?query#ref"), | |
1165 std::string(), | |
1166 kFormatUrlOmitUsernamePassword, | |
1167 UnescapeRule::NORMAL, | |
1168 &parsed, | |
1169 NULL, | |
1170 NULL); | |
1171 EXPECT_EQ(WideToUTF16(L"view-source:http://host:81/path?query#ref"), | |
1172 formatted); | |
1173 EXPECT_EQ(WideToUTF16(L"view-source:http"), | |
1174 formatted.substr(parsed.scheme.begin, parsed.scheme.len)); | |
1175 EXPECT_FALSE(parsed.username.is_valid()); | |
1176 EXPECT_FALSE(parsed.password.is_valid()); | |
1177 EXPECT_EQ(WideToUTF16(L"host"), | |
1178 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1179 EXPECT_EQ(WideToUTF16(L"81"), | |
1180 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1181 EXPECT_EQ(WideToUTF16(L"/path"), | |
1182 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1183 EXPECT_EQ(WideToUTF16(L"query"), | |
1184 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1185 EXPECT_EQ(WideToUTF16(L"ref"), | |
1186 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1187 | |
1188 // omit http case. | |
1189 formatted = FormatUrl(GURL("http://host:8000/a?b=c#d"), | |
1190 std::string(), | |
1191 kFormatUrlOmitHTTP, | |
1192 UnescapeRule::NORMAL, | |
1193 &parsed, | |
1194 NULL, | |
1195 NULL); | |
1196 EXPECT_EQ(WideToUTF16(L"host:8000/a?b=c#d"), formatted); | |
1197 EXPECT_FALSE(parsed.scheme.is_valid()); | |
1198 EXPECT_FALSE(parsed.username.is_valid()); | |
1199 EXPECT_FALSE(parsed.password.is_valid()); | |
1200 EXPECT_EQ(WideToUTF16(L"host"), | |
1201 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1202 EXPECT_EQ(WideToUTF16(L"8000"), | |
1203 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1204 EXPECT_EQ(WideToUTF16(L"/a"), | |
1205 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1206 EXPECT_EQ(WideToUTF16(L"b=c"), | |
1207 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1208 EXPECT_EQ(WideToUTF16(L"d"), | |
1209 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1210 | |
1211 // omit http starts with ftp case. | |
1212 formatted = FormatUrl(GURL("http://ftp.host:8000/a?b=c#d"), | |
1213 std::string(), | |
1214 kFormatUrlOmitHTTP, | |
1215 UnescapeRule::NORMAL, | |
1216 &parsed, | |
1217 NULL, | |
1218 NULL); | |
1219 EXPECT_EQ(WideToUTF16(L"http://ftp.host:8000/a?b=c#d"), formatted); | |
1220 EXPECT_TRUE(parsed.scheme.is_valid()); | |
1221 EXPECT_FALSE(parsed.username.is_valid()); | |
1222 EXPECT_FALSE(parsed.password.is_valid()); | |
1223 EXPECT_EQ(WideToUTF16(L"http"), | |
1224 formatted.substr(parsed.scheme.begin, parsed.scheme.len)); | |
1225 EXPECT_EQ(WideToUTF16(L"ftp.host"), | |
1226 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1227 EXPECT_EQ(WideToUTF16(L"8000"), | |
1228 formatted.substr(parsed.port.begin, parsed.port.len)); | |
1229 EXPECT_EQ(WideToUTF16(L"/a"), | |
1230 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1231 EXPECT_EQ(WideToUTF16(L"b=c"), | |
1232 formatted.substr(parsed.query.begin, parsed.query.len)); | |
1233 EXPECT_EQ(WideToUTF16(L"d"), | |
1234 formatted.substr(parsed.ref.begin, parsed.ref.len)); | |
1235 | |
1236 // omit http starts with 'f' case. | |
1237 formatted = FormatUrl(GURL("http://f/"), | |
1238 std::string(), | |
1239 kFormatUrlOmitHTTP, | |
1240 UnescapeRule::NORMAL, | |
1241 &parsed, | |
1242 NULL, | |
1243 NULL); | |
1244 EXPECT_EQ(WideToUTF16(L"f/"), formatted); | |
1245 EXPECT_FALSE(parsed.scheme.is_valid()); | |
1246 EXPECT_FALSE(parsed.username.is_valid()); | |
1247 EXPECT_FALSE(parsed.password.is_valid()); | |
1248 EXPECT_FALSE(parsed.port.is_valid()); | |
1249 EXPECT_TRUE(parsed.path.is_valid()); | |
1250 EXPECT_FALSE(parsed.query.is_valid()); | |
1251 EXPECT_FALSE(parsed.ref.is_valid()); | |
1252 EXPECT_EQ(WideToUTF16(L"f"), | |
1253 formatted.substr(parsed.host.begin, parsed.host.len)); | |
1254 EXPECT_EQ(WideToUTF16(L"/"), | |
1255 formatted.substr(parsed.path.begin, parsed.path.len)); | |
1256 } | |
1257 | |
1258 // Make sure that calling FormatUrl on a GURL and then converting back to a GURL | |
1259 // results in the original GURL, for each ASCII character in the path. | |
1260 TEST(NetUtilTest, FormatUrlRoundTripPathASCII) { | |
1261 for (unsigned char test_char = 32; test_char < 128; ++test_char) { | |
1262 GURL url(std::string("http://www.google.com/") + | |
1263 static_cast<char>(test_char)); | |
1264 size_t prefix_len; | |
1265 base::string16 formatted = FormatUrl(url, | |
1266 std::string(), | |
1267 kFormatUrlOmitUsernamePassword, | |
1268 UnescapeRule::NORMAL, | |
1269 NULL, | |
1270 &prefix_len, | |
1271 NULL); | |
1272 EXPECT_EQ(url.spec(), GURL(formatted).spec()); | |
1273 } | |
1274 } | |
1275 | |
1276 // Make sure that calling FormatUrl on a GURL and then converting back to a GURL | |
1277 // results in the original GURL, for each escaped ASCII character in the path. | |
1278 TEST(NetUtilTest, FormatUrlRoundTripPathEscaped) { | |
1279 for (unsigned char test_char = 32; test_char < 128; ++test_char) { | |
1280 std::string original_url("http://www.google.com/"); | |
1281 original_url.push_back('%'); | |
1282 original_url.append(base::HexEncode(&test_char, 1)); | |
1283 | |
1284 GURL url(original_url); | |
1285 size_t prefix_len; | |
1286 base::string16 formatted = FormatUrl(url, | |
1287 std::string(), | |
1288 kFormatUrlOmitUsernamePassword, | |
1289 UnescapeRule::NORMAL, | |
1290 NULL, | |
1291 &prefix_len, | |
1292 NULL); | |
1293 EXPECT_EQ(url.spec(), GURL(formatted).spec()); | |
1294 } | |
1295 } | |
1296 | |
1297 // Make sure that calling FormatUrl on a GURL and then converting back to a GURL | |
1298 // results in the original GURL, for each ASCII character in the query. | |
1299 TEST(NetUtilTest, FormatUrlRoundTripQueryASCII) { | |
1300 for (unsigned char test_char = 32; test_char < 128; ++test_char) { | |
1301 GURL url(std::string("http://www.google.com/?") + | |
1302 static_cast<char>(test_char)); | |
1303 size_t prefix_len; | |
1304 base::string16 formatted = FormatUrl(url, | |
1305 std::string(), | |
1306 kFormatUrlOmitUsernamePassword, | |
1307 UnescapeRule::NORMAL, | |
1308 NULL, | |
1309 &prefix_len, | |
1310 NULL); | |
1311 EXPECT_EQ(url.spec(), GURL(formatted).spec()); | |
1312 } | |
1313 } | |
1314 | |
1315 // Make sure that calling FormatUrl on a GURL and then converting back to a GURL | |
1316 // only results in a different GURL for certain characters. | |
1317 TEST(NetUtilTest, FormatUrlRoundTripQueryEscaped) { | |
1318 // A full list of characters which FormatURL should unescape and GURL should | |
1319 // not escape again, when they appear in a query string. | |
1320 const char* kUnescapedCharacters = | |
1321 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~"; | |
1322 for (unsigned char test_char = 0; test_char < 128; ++test_char) { | |
1323 std::string original_url("http://www.google.com/?"); | |
1324 original_url.push_back('%'); | |
1325 original_url.append(base::HexEncode(&test_char, 1)); | |
1326 | |
1327 GURL url(original_url); | |
1328 size_t prefix_len; | |
1329 base::string16 formatted = FormatUrl(url, | |
1330 std::string(), | |
1331 kFormatUrlOmitUsernamePassword, | |
1332 UnescapeRule::NORMAL, | |
1333 NULL, | |
1334 &prefix_len, | |
1335 NULL); | |
1336 | |
1337 if (test_char && | |
1338 strchr(kUnescapedCharacters, static_cast<char>(test_char))) { | |
1339 EXPECT_NE(url.spec(), GURL(formatted).spec()); | |
1340 } else { | |
1341 EXPECT_EQ(url.spec(), GURL(formatted).spec()); | |
1342 } | |
1343 } | |
1344 } | |
1345 | |
1346 TEST(NetUtilTest, FormatUrlWithOffsets) { | |
1347 CheckAdjustedOffsets(std::string(), "en", kFormatUrlOmitNothing, | |
1348 UnescapeRule::NORMAL, NULL); | |
1349 | |
1350 const size_t basic_offsets[] = { | |
1351 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |
1352 21, 22, 23, 24, 25 | |
1353 }; | |
1354 CheckAdjustedOffsets("http://www.google.com/foo/", "en", | |
1355 kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
1356 basic_offsets); | |
1357 | |
1358 const size_t omit_auth_offsets_1[] = { | |
1359 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 7, | |
1360 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 | |
1361 }; | |
1362 CheckAdjustedOffsets("http://foo:bar@www.google.com/", "en", | |
1363 kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, | |
1364 omit_auth_offsets_1); | |
1365 | |
1366 const size_t omit_auth_offsets_2[] = { | |
1367 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, 7, 8, 9, 10, 11, 12, 13, 14, | |
1368 15, 16, 17, 18, 19, 20, 21 | |
1369 }; | |
1370 CheckAdjustedOffsets("http://foo@www.google.com/", "en", | |
1371 kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, | |
1372 omit_auth_offsets_2); | |
1373 | |
1374 const size_t dont_omit_auth_offsets[] = { | |
1375 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1376 kNpos, kNpos, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1377 kNpos, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, | |
1378 30, 31 | |
1379 }; | |
1380 // Unescape to "http://foo\x30B0:\x30B0bar@www.google.com". | |
1381 CheckAdjustedOffsets("http://foo%E3%82%B0:%E3%82%B0bar@www.google.com/", "en", | |
1382 kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
1383 dont_omit_auth_offsets); | |
1384 | |
1385 const size_t view_source_offsets[] = { | |
1386 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, kNpos, | |
1387 kNpos, kNpos, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 | |
1388 }; | |
1389 CheckAdjustedOffsets("view-source:http://foo@www.google.com/", "en", | |
1390 kFormatUrlOmitUsernamePassword, UnescapeRule::NORMAL, | |
1391 view_source_offsets); | |
1392 | |
1393 const size_t idn_hostname_offsets_1[] = { | |
1394 0, 1, 2, 3, 4, 5, 6, 7, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1395 kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 12, | |
1396 13, 14, 15, 16, 17, 18, 19 | |
1397 }; | |
1398 // Convert punycode to "http://\x671d\x65e5\x3042\x3055\x3072.jp/foo/". | |
1399 CheckAdjustedOffsets("http://xn--l8jvb1ey91xtjb.jp/foo/", "ja", | |
1400 kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
1401 idn_hostname_offsets_1); | |
1402 | |
1403 const size_t idn_hostname_offsets_2[] = { | |
1404 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1405 kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 14, 15, kNpos, kNpos, kNpos, | |
1406 kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1407 kNpos, 19, 20, 21, 22, 23, 24 | |
1408 }; | |
1409 // Convert punycode to | |
1410 // "http://test.\x89c6\x9891.\x5317\x4eac\x5927\x5b78.test/". | |
1411 CheckAdjustedOffsets("http://test.xn--cy2a840a.xn--1lq90ic7f1rc.test/", | |
1412 "zh-CN", kFormatUrlOmitNothing, UnescapeRule::NORMAL, | |
1413 idn_hostname_offsets_2); | |
1414 | |
1415 const size_t unescape_offsets[] = { | |
1416 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |
1417 21, 22, 23, 24, 25, kNpos, kNpos, 26, 27, 28, 29, 30, kNpos, kNpos, kNpos, | |
1418 kNpos, kNpos, kNpos, kNpos, kNpos, 31, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1419 kNpos, kNpos, kNpos, 32, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, | |
1420 kNpos, 33, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos | |
1421 }; | |
1422 // Unescape to "http://www.google.com/foo bar/\x30B0\x30FC\x30B0\x30EB". | |
1423 CheckAdjustedOffsets( | |
1424 "http://www.google.com/foo%20bar/%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB", | |
1425 "en", kFormatUrlOmitNothing, UnescapeRule::SPACES, unescape_offsets); | |
1426 | |
1427 const size_t ref_offsets[] = { | |
1428 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |
1429 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, kNpos, kNpos, 32, kNpos, kNpos, | |
1430 33 | |
1431 }; | |
1432 // Unescape to "http://www.google.com/foo.html#\x30B0\x30B0z". | |
1433 CheckAdjustedOffsets( | |
1434 "http://www.google.com/foo.html#\xE3\x82\xB0\xE3\x82\xB0z", "en", | |
1435 kFormatUrlOmitNothing, UnescapeRule::NORMAL, ref_offsets); | |
1436 | |
1437 const size_t omit_http_offsets[] = { | |
1438 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
1439 10, 11, 12, 13, 14 | |
1440 }; | |
1441 CheckAdjustedOffsets("http://www.google.com/", "en", kFormatUrlOmitHTTP, | |
1442 UnescapeRule::NORMAL, omit_http_offsets); | |
1443 | |
1444 const size_t omit_http_start_with_ftp_offsets[] = { | |
1445 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 | |
1446 }; | |
1447 CheckAdjustedOffsets("http://ftp.google.com/", "en", kFormatUrlOmitHTTP, | |
1448 UnescapeRule::NORMAL, omit_http_start_with_ftp_offsets); | |
1449 | |
1450 const size_t omit_all_offsets[] = { | |
1451 0, kNpos, kNpos, kNpos, kNpos, kNpos, kNpos, 0, kNpos, kNpos, kNpos, kNpos, | |
1452 0, 1, 2, 3, 4, 5, 6, 7 | |
1453 }; | |
1454 CheckAdjustedOffsets("http://user@foo.com/", "en", kFormatUrlOmitAll, | |
1455 UnescapeRule::NORMAL, omit_all_offsets); | |
1456 } | |
1457 | |
1458 TEST(NetUtilTest, SimplifyUrlForRequest) { | 408 TEST(NetUtilTest, SimplifyUrlForRequest) { |
1459 struct { | 409 struct { |
1460 const char* input_url; | 410 const char* input_url; |
1461 const char* expected_simplified_url; | 411 const char* expected_simplified_url; |
1462 } tests[] = { | 412 } tests[] = { |
1463 { | 413 { |
1464 // Reference section should be stripped. | 414 // Reference section should be stripped. |
1465 "http://www.google.com:78/foobar?query=1#hash", | 415 "http://www.google.com:78/foobar?query=1#hash", |
1466 "http://www.google.com:78/foobar?query=1", | 416 "http://www.google.com:78/foobar?query=1", |
1467 }, | 417 }, |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 TEST_P(NetUtilNonUniqueNameTest, IsHostnameNonUnique) { | 839 TEST_P(NetUtilNonUniqueNameTest, IsHostnameNonUnique) { |
1890 const NonUniqueNameTestData& test_data = GetParam(); | 840 const NonUniqueNameTestData& test_data = GetParam(); |
1891 | 841 |
1892 EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname)); | 842 EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname)); |
1893 } | 843 } |
1894 | 844 |
1895 INSTANTIATE_TEST_CASE_P(, NetUtilNonUniqueNameTest, | 845 INSTANTIATE_TEST_CASE_P(, NetUtilNonUniqueNameTest, |
1896 testing::ValuesIn(kNonUniqueNameTestData)); | 846 testing::ValuesIn(kNonUniqueNameTestData)); |
1897 | 847 |
1898 } // namespace net | 848 } // namespace net |
OLD | NEW |