• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "url/gurl.h"
9 #include "webkit/browser/appcache/manifest_parser.h"
10 
11 using appcache::Manifest;
12 using appcache::NamespaceVector;
13 using appcache::APPCACHE_FALLBACK_NAMESPACE;
14 using appcache::APPCACHE_INTERCEPT_NAMESPACE;
15 using appcache::APPCACHE_NETWORK_NAMESPACE;
16 using appcache::PARSE_MANIFEST_ALLOWING_INTERCEPTS;
17 using appcache::PARSE_MANIFEST_PER_STANDARD;
18 
19 namespace content {
20 
21 class AppCacheManifestParserTest : public testing::Test {
22 };
23 
TEST(AppCacheManifestParserTest,NoData)24 TEST(AppCacheManifestParserTest, NoData) {
25   GURL url;
26   Manifest manifest;
27   EXPECT_FALSE(ParseManifest(url, "", 0,
28                              PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
29   EXPECT_FALSE(ParseManifest(url, "CACHE MANIFEST\r", 0,  // Len is 0.
30                              PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
31 }
32 
TEST(AppCacheManifestParserTest,CheckSignature)33 TEST(AppCacheManifestParserTest, CheckSignature) {
34   GURL url;
35   Manifest manifest;
36 
37   const std::string kBadSignatures[] = {
38     "foo",
39     "CACHE MANIFEST;V2\r",          // not followed by whitespace
40     "CACHE MANIFEST#bad\r",         // no whitespace before comment
41     "cache manifest ",              // wrong case
42     "#CACHE MANIFEST\r",            // comment
43     "xCACHE MANIFEST\n",            // bad first char
44     " CACHE MANIFEST\r",            // begins with whitespace
45     "\xEF\xBE\xBF" "CACHE MANIFEST\r",  // bad UTF-8 BOM value
46   };
47 
48   for (size_t i = 0; i < arraysize(kBadSignatures); ++i) {
49     const std::string bad = kBadSignatures[i];
50     EXPECT_FALSE(ParseManifest(url, bad.c_str(), bad.length(),
51                                PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
52   }
53 
54   const std::string kGoodSignatures[] = {
55     "CACHE MANIFEST",
56     "CACHE MANIFEST ",
57     "CACHE MANIFEST\r",
58     "CACHE MANIFEST\n",
59     "CACHE MANIFEST\r\n",
60     "CACHE MANIFEST\t# ignore me\r",
61     "CACHE MANIFEST ignore\r\n",
62     "CHROMIUM CACHE MANIFEST\r\n",
63     "\xEF\xBB\xBF" "CACHE MANIFEST \r\n",   // BOM present
64   };
65 
66   for (size_t i = 0; i < arraysize(kGoodSignatures); ++i) {
67     const std::string good = kGoodSignatures[i];
68     EXPECT_TRUE(ParseManifest(url, good.c_str(), good.length(),
69                               PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
70   }
71 }
72 
TEST(AppCacheManifestParserTest,NoManifestUrl)73 TEST(AppCacheManifestParserTest, NoManifestUrl) {
74   Manifest manifest;
75   const std::string kData("CACHE MANIFEST\r"
76     "relative/tobase.com\r"
77     "http://absolute.com/addme.com");
78   const GURL kUrl;
79   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
80                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
81   EXPECT_TRUE(manifest.explicit_urls.empty());
82   EXPECT_TRUE(manifest.fallback_namespaces.empty());
83   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
84   EXPECT_FALSE(manifest.online_whitelist_all);
85 }
86 
TEST(AppCacheManifestParserTest,ExplicitUrls)87 TEST(AppCacheManifestParserTest, ExplicitUrls) {
88   Manifest manifest;
89   const GURL kUrl("http://www.foo.com");
90   const std::string kData("CACHE MANIFEST\r"
91     "relative/one\r"
92     "# some comment\r"
93     "http://www.foo.com/two#strip\r\n"
94     "NETWORK:\r"
95     "  \t CACHE:\r"
96     "HTTP://www.diff.com/three\r"
97     "FALLBACK:\r"
98     " \t # another comment with leading whitespace\n"
99     "IGNORE:\r"
100     "http://www.foo.com/ignore\r"
101     "CACHE: \r"
102     "garbage:#!@\r"
103     "https://www.foo.com/diffscheme \t \r"
104     "  \t relative/four#stripme\n\r"
105     "*\r");
106 
107   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
108                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
109   EXPECT_TRUE(manifest.fallback_namespaces.empty());
110   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
111   EXPECT_FALSE(manifest.online_whitelist_all);
112 
113   base::hash_set<std::string> urls = manifest.explicit_urls;
114   const size_t kExpected = 5;
115   ASSERT_EQ(kExpected, urls.size());
116   EXPECT_TRUE(urls.find("http://www.foo.com/relative/one") != urls.end());
117   EXPECT_TRUE(urls.find("http://www.foo.com/two") != urls.end());
118   EXPECT_TRUE(urls.find("http://www.diff.com/three") != urls.end());
119   EXPECT_TRUE(urls.find("http://www.foo.com/relative/four") != urls.end());
120 
121   // Wildcard is treated as a relative URL in explicit section.
122   EXPECT_TRUE(urls.find("http://www.foo.com/*") != urls.end());
123 
124   // We should get the same results with intercepts disallowed.
125   manifest = Manifest();
126   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
127                             PARSE_MANIFEST_PER_STANDARD, manifest));
128   EXPECT_TRUE(manifest.fallback_namespaces.empty());
129   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
130   EXPECT_FALSE(manifest.online_whitelist_all);
131 
132   urls = manifest.explicit_urls;
133   ASSERT_EQ(kExpected, urls.size());
134   EXPECT_TRUE(urls.find("http://www.foo.com/relative/one") != urls.end());
135   EXPECT_TRUE(urls.find("http://www.foo.com/two") != urls.end());
136   EXPECT_TRUE(urls.find("http://www.diff.com/three") != urls.end());
137   EXPECT_TRUE(urls.find("http://www.foo.com/relative/four") != urls.end());
138 
139   // Wildcard is treated as a relative URL in explicit section.
140   EXPECT_TRUE(urls.find("http://www.foo.com/*") != urls.end());
141 }
142 
TEST(AppCacheManifestParserTest,WhitelistUrls)143 TEST(AppCacheManifestParserTest, WhitelistUrls) {
144   Manifest manifest;
145   const GURL kUrl("http://www.bar.com");
146   const std::string kData("CACHE MANIFEST\r"
147     "NETWORK:\r"
148     "relative/one\r"
149     "# a comment\r"
150     "http://www.bar.com/two\r"
151     "HTTP://www.diff.com/three#strip\n\r"
152     "FALLBACK:\r"
153     "garbage\r"
154     "UNKNOWN:\r"
155     "http://www.bar.com/ignore\r"
156     "CACHE:\r"
157     "NETWORK:\r"
158     "https://www.wrongscheme.com\n"
159     "relative/four#stripref \t \r"
160     "http://www.five.com\r\n"
161     "*foo\r");
162 
163   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
164                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
165   EXPECT_TRUE(manifest.explicit_urls.empty());
166   EXPECT_TRUE(manifest.fallback_namespaces.empty());
167   EXPECT_TRUE(manifest.intercept_namespaces.empty());
168   EXPECT_FALSE(manifest.online_whitelist_all);
169 
170   const NamespaceVector& online = manifest.online_whitelist_namespaces;
171   const size_t kExpected = 6;
172   ASSERT_EQ(kExpected, online.size());
173   EXPECT_EQ(APPCACHE_NETWORK_NAMESPACE, online[0].type);
174   EXPECT_FALSE(online[0].is_pattern);
175   EXPECT_TRUE(online[0].target_url.is_empty());
176   EXPECT_EQ(GURL("http://www.bar.com/relative/one"), online[0].namespace_url);
177   EXPECT_EQ(GURL("http://www.bar.com/two"), online[1].namespace_url);
178   EXPECT_EQ(GURL("http://www.diff.com/three"), online[2].namespace_url);
179   EXPECT_EQ(GURL("http://www.bar.com/relative/four"), online[3].namespace_url);
180   EXPECT_EQ(GURL("http://www.five.com"), online[4].namespace_url);
181   EXPECT_EQ(GURL("http://www.bar.com/*foo"), online[5].namespace_url);
182 }
183 
TEST(AppCacheManifestParserTest,FallbackUrls)184 TEST(AppCacheManifestParserTest, FallbackUrls) {
185   Manifest manifest;
186   const GURL kUrl("http://glorp.com");
187   const std::string kData("CACHE MANIFEST\r"
188     "# a comment\r"
189     "CACHE:\r"
190     "NETWORK:\r"
191     "UNKNOWN:\r"
192     "FALLBACK:\r"
193     "relative/one \t \t http://glorp.com/onefb  \t \r"
194     "*\r"
195     "https://glorp.com/wrong http://glorp.com/wrongfb\r"
196     "http://glorp.com/two#strip relative/twofb\r"
197     "HTTP://glorp.com/three relative/threefb#strip\n"
198     "http://glorp.com/three http://glorp.com/three-dup\r"
199     "http://glorp.com/solo \t \r\n"
200     "http://diff.com/ignore http://glorp.com/wronghost\r"
201     "http://glorp.com/wronghost http://diff.com/ohwell\r"
202     "relative/badscheme ftp://glorp.com/ignored\r"
203     "garbage\r\n"
204     "CACHE:\r"
205     "# only fallback urls in this test\r"
206     "FALLBACK:\n"
207     "relative/four#strip relative/fourfb#strip\r"
208     "http://www.glorp.com/notsame relative/skipped\r");
209 
210   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
211                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
212   EXPECT_TRUE(manifest.explicit_urls.empty());
213   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
214   EXPECT_FALSE(manifest.online_whitelist_all);
215 
216   const NamespaceVector& fallbacks = manifest.fallback_namespaces;
217   const size_t kExpected = 5;
218   ASSERT_EQ(kExpected, fallbacks.size());
219   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type);
220   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type);
221   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[2].type);
222   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[3].type);
223   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[4].type);
224   EXPECT_EQ(GURL("http://glorp.com/relative/one"),
225             fallbacks[0].namespace_url);
226   EXPECT_EQ(GURL("http://glorp.com/onefb"),
227             fallbacks[0].target_url);
228   EXPECT_EQ(GURL("http://glorp.com/two"),
229             fallbacks[1].namespace_url);
230   EXPECT_EQ(GURL("http://glorp.com/relative/twofb"),
231             fallbacks[1].target_url);
232   EXPECT_EQ(GURL("http://glorp.com/three"),
233             fallbacks[2].namespace_url);
234   EXPECT_EQ(GURL("http://glorp.com/relative/threefb"),
235             fallbacks[2].target_url);
236   EXPECT_EQ(GURL("http://glorp.com/three"),       // duplicates are stored
237             fallbacks[3].namespace_url);
238   EXPECT_EQ(GURL("http://glorp.com/three-dup"),
239             fallbacks[3].target_url);
240   EXPECT_EQ(GURL("http://glorp.com/relative/four"),
241             fallbacks[4].namespace_url);
242   EXPECT_EQ(GURL("http://glorp.com/relative/fourfb"),
243             fallbacks[4].target_url);
244 
245   EXPECT_TRUE(manifest.intercept_namespaces.empty());
246 }
247 
TEST(AppCacheManifestParserTest,FallbackUrlsWithPort)248 TEST(AppCacheManifestParserTest, FallbackUrlsWithPort) {
249   Manifest manifest;
250   const GURL kUrl("http://www.portme.com:1234");
251   const std::string kData("CACHE MANIFEST\r"
252     "FALLBACK:\r"
253     "http://www.portme.com:1234/one relative/onefb\r"
254     "HTTP://www.portme.com:9876/wrong http://www.portme.com:1234/ignore\r"
255     "http://www.portme.com:1234/stillwrong http://www.portme.com:42/boo\r"
256     "relative/two relative/twofb\r"
257     "http://www.portme.com:1234/three HTTP://www.portme.com:1234/threefb\r"
258     "http://www.portme.com/noport http://www.portme.com:1234/skipped\r"
259     "http://www.portme.com:1234/skipme http://www.portme.com/noport\r");
260 
261   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
262                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
263   EXPECT_TRUE(manifest.explicit_urls.empty());
264   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
265   EXPECT_FALSE(manifest.online_whitelist_all);
266 
267   const NamespaceVector& fallbacks = manifest.fallback_namespaces;
268   const size_t kExpected = 3;
269   ASSERT_EQ(kExpected, fallbacks.size());
270   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type);
271   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type);
272   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[2].type);
273   EXPECT_EQ(GURL("http://www.portme.com:1234/one"),
274             fallbacks[0].namespace_url);
275   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/onefb"),
276             fallbacks[0].target_url);
277   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/two"),
278             fallbacks[1].namespace_url);
279   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/twofb"),
280             fallbacks[1].target_url);
281   EXPECT_EQ(GURL("http://www.portme.com:1234/three"),
282             fallbacks[2].namespace_url);
283   EXPECT_EQ(GURL("http://www.portme.com:1234/threefb"),
284             fallbacks[2].target_url);
285 
286   EXPECT_TRUE(manifest.intercept_namespaces.empty());
287 }
288 
TEST(AppCacheManifestParserTest,InterceptUrls)289 TEST(AppCacheManifestParserTest, InterceptUrls) {
290   Manifest manifest;
291   const GURL kUrl("http://www.portme.com:1234");
292   const std::string kData("CHROMIUM CACHE MANIFEST\r"
293     "CHROMIUM-INTERCEPT:\r"
294     "http://www.portme.com:1234/one return relative/int1\r"
295     "HTTP://www.portme.com:9/wrong return http://www.portme.com:1234/ignore\r"
296     "http://www.portme.com:1234/wrong return http://www.portme.com:9/boo\r"
297     "relative/two return relative/int2\r"
298     "relative/three wrong relative/threefb\r"
299     "http://www.portme.com:1234/three return HTTP://www.portme.com:1234/int3\r"
300     "http://www.portme.com/noport return http://www.portme.com:1234/skipped\r"
301     "http://www.portme.com:1234/skipme return http://www.portme.com/noport\r"
302     "relative/wrong/again missing/intercept_type\r");
303 
304   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
305                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
306   EXPECT_TRUE(manifest.fallback_namespaces.empty());
307   EXPECT_TRUE(manifest.explicit_urls.empty());
308   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
309   EXPECT_FALSE(manifest.online_whitelist_all);
310 
311   const NamespaceVector& intercepts = manifest.intercept_namespaces;
312   const size_t kExpected = 3;
313   ASSERT_EQ(kExpected, intercepts.size());
314   EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[0].type);
315   EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[1].type);
316   EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE, intercepts[2].type);
317   EXPECT_EQ(GURL("http://www.portme.com:1234/one"),
318             intercepts[0].namespace_url);
319   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/int1"),
320             intercepts[0].target_url);
321   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/two"),
322             intercepts[1].namespace_url);
323   EXPECT_EQ(GURL("http://www.portme.com:1234/relative/int2"),
324             intercepts[1].target_url);
325   EXPECT_EQ(GURL("http://www.portme.com:1234/three"),
326             intercepts[2].namespace_url);
327   EXPECT_EQ(GURL("http://www.portme.com:1234/int3"),
328             intercepts[2].target_url);
329 
330   // Disallow intercepts ths time.
331   manifest = Manifest();
332   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
333                             PARSE_MANIFEST_PER_STANDARD, manifest));
334   EXPECT_TRUE(manifest.fallback_namespaces.empty());
335   EXPECT_TRUE(manifest.explicit_urls.empty());
336   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
337   EXPECT_TRUE(manifest.intercept_namespaces.empty());
338   EXPECT_FALSE(manifest.online_whitelist_all);
339 }
340 
TEST(AppCacheManifestParserTest,ComboUrls)341 TEST(AppCacheManifestParserTest, ComboUrls) {
342   Manifest manifest;
343   const GURL kUrl("http://combo.com:42");
344   const std::string kData("CACHE MANIFEST\r"
345     "relative/explicit-1\r"
346     "# some comment\r"
347     "http://combo.com:99/explicit-2#strip\r"
348     "NETWORK:\r"
349     "http://combo.com/whitelist-1\r"
350     "HTTP://www.diff.com/whitelist-2#strip\r"
351     "*\r"
352     "CACHE:\n\r"
353     "http://www.diff.com/explicit-3\r"
354     "FALLBACK:\r"
355     "http://combo.com:42/fallback-1 http://combo.com:42/fallback-1b\r"
356     "relative/fallback-2 relative/fallback-2b\r"
357     "UNKNOWN:\r\n"
358     "http://combo.com/ignoreme\r"
359     "relative/still-ignored\r"
360     "NETWORK:\r\n"
361     "relative/whitelist-3#strip\r"
362     "http://combo.com:99/whitelist-4\r");
363   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
364                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
365   EXPECT_TRUE(manifest.online_whitelist_all);
366 
367   base::hash_set<std::string> urls = manifest.explicit_urls;
368   size_t expected = 3;
369   ASSERT_EQ(expected, urls.size());
370   EXPECT_TRUE(urls.find("http://combo.com:42/relative/explicit-1") !=
371               urls.end());
372   EXPECT_TRUE(urls.find("http://combo.com:99/explicit-2") != urls.end());
373   EXPECT_TRUE(urls.find("http://www.diff.com/explicit-3") != urls.end());
374 
375   const NamespaceVector& online = manifest.online_whitelist_namespaces;
376   expected = 4;
377   ASSERT_EQ(expected, online.size());
378   EXPECT_EQ(GURL("http://combo.com/whitelist-1"),
379                  online[0].namespace_url);
380   EXPECT_EQ(GURL("http://www.diff.com/whitelist-2"),
381                  online[1].namespace_url);
382   EXPECT_EQ(GURL("http://combo.com:42/relative/whitelist-3"),
383                  online[2].namespace_url);
384   EXPECT_EQ(GURL("http://combo.com:99/whitelist-4"),
385                  online[3].namespace_url);
386 
387   const NamespaceVector& fallbacks = manifest.fallback_namespaces;
388   expected = 2;
389   ASSERT_EQ(expected, fallbacks.size());
390   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[0].type);
391   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[1].type);
392   EXPECT_EQ(GURL("http://combo.com:42/fallback-1"),
393             fallbacks[0].namespace_url);
394   EXPECT_EQ(GURL("http://combo.com:42/fallback-1b"),
395             fallbacks[0].target_url);
396   EXPECT_EQ(GURL("http://combo.com:42/relative/fallback-2"),
397             fallbacks[1].namespace_url);
398   EXPECT_EQ(GURL("http://combo.com:42/relative/fallback-2b"),
399             fallbacks[1].target_url);
400 
401   EXPECT_TRUE(manifest.intercept_namespaces.empty());
402 }
403 
TEST(AppCacheManifestParserTest,UnusualUtf8)404 TEST(AppCacheManifestParserTest, UnusualUtf8) {
405   Manifest manifest;
406   const GURL kUrl("http://bad.com");
407   const std::string kData("CACHE MANIFEST\r"
408     "\xC0" "invalidutf8\r"
409     "nonbmp" "\xF1\x84\xAB\xBC\r");
410   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
411                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
412   base::hash_set<std::string> urls = manifest.explicit_urls;
413   EXPECT_TRUE(urls.find("http://bad.com/%EF%BF%BDinvalidutf8") != urls.end());
414   EXPECT_TRUE(urls.find("http://bad.com/nonbmp%F1%84%AB%BC") != urls.end());
415 }
416 
TEST(AppCacheManifestParserTest,IgnoreAfterSpace)417 TEST(AppCacheManifestParserTest, IgnoreAfterSpace) {
418   Manifest manifest;
419   const GURL kUrl("http://smorg.borg");
420   const std::string kData(
421     "CACHE MANIFEST\r"
422     "resource.txt this stuff after the white space should be ignored\r");
423   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
424                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
425 
426   base::hash_set<std::string> urls = manifest.explicit_urls;
427   EXPECT_TRUE(urls.find("http://smorg.borg/resource.txt") != urls.end());
428 }
429 
TEST(AppCacheManifestParserTest,DifferentOriginUrlWithSecureScheme)430 TEST(AppCacheManifestParserTest, DifferentOriginUrlWithSecureScheme) {
431   Manifest manifest;
432   const GURL kUrl("https://www.foo.com");
433   const std::string kData("CACHE MANIFEST\r"
434     "CACHE: \r"
435     "relative/secureschemesameorigin\r"
436     "https://www.foo.com/secureschemesameorigin\r"
437     "http://www.xyz.com/secureschemedifforigin\r"
438     "https://www.xyz.com/secureschemedifforigin\r");
439 
440   EXPECT_TRUE(ParseManifest(kUrl, kData.c_str(), kData.length(),
441                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
442   EXPECT_TRUE(manifest.fallback_namespaces.empty());
443   EXPECT_TRUE(manifest.online_whitelist_namespaces.empty());
444 
445   base::hash_set<std::string> urls = manifest.explicit_urls;
446   const size_t kExpected = 3;
447   ASSERT_EQ(kExpected, urls.size());
448   EXPECT_TRUE(urls.find("https://www.foo.com/relative/secureschemesameorigin")
449       != urls.end());
450   EXPECT_TRUE(urls.find("https://www.foo.com/secureschemesameorigin") !=
451       urls.end());
452   EXPECT_FALSE(urls.find("http://www.xyz.com/secureschemedifforigin") !=
453       urls.end());
454   EXPECT_TRUE(urls.find("https://www.xyz.com/secureschemedifforigin") !=
455       urls.end());
456 }
457 
TEST(AppCacheManifestParserTest,PatternMatching)458 TEST(AppCacheManifestParserTest, PatternMatching) {
459   const GURL kUrl("http://foo.com/manifest");
460   const std::string kManifestBody(
461       "CACHE MANIFEST\r"
462       "CACHE: \r"
463       "http://foo.com/page.html\r"
464       "CHROMIUM-INTERCEPT:\r"
465       "http://foo.com/intercept_prefix return /prefix\r"
466       "http://foo.com/intercept_pattern return /pattern isPattern\r"
467       "http://foo.com/*/intercept_pattern?query return /pattern isPattern\r"
468       "FALLBACK:\r"
469       "http://foo.com/fallback_prefix  /prefix wrongAnnotation\r"
470       "http://foo.com/fallback_pattern* /pattern\tisPattern    \r"
471       "NETWORK:\r"
472       "*\r"
473       "isPattern\r"  // should not be interpretted as a pattern
474       "http://foo.com/network_pattern* isPattern\r");
475 
476 
477   Manifest manifest;
478   EXPECT_TRUE(ParseManifest(kUrl, kManifestBody.c_str(),
479                             kManifestBody.length(),
480                             PARSE_MANIFEST_ALLOWING_INTERCEPTS, manifest));
481   EXPECT_TRUE(manifest.online_whitelist_all);
482   EXPECT_EQ(1u, manifest.explicit_urls.size());
483   EXPECT_EQ(3u, manifest.intercept_namespaces.size());
484   EXPECT_EQ(2u, manifest.fallback_namespaces.size());
485   EXPECT_EQ(2u, manifest.online_whitelist_namespaces.size());
486   EXPECT_EQ(APPCACHE_INTERCEPT_NAMESPACE,
487             manifest.intercept_namespaces[0].type);
488   EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, manifest.fallback_namespaces[0].type);
489   EXPECT_EQ(APPCACHE_NETWORK_NAMESPACE,
490             manifest.online_whitelist_namespaces[0].type);
491   EXPECT_FALSE(manifest.intercept_namespaces[0].is_pattern);
492   EXPECT_TRUE(manifest.intercept_namespaces[1].is_pattern);
493   EXPECT_TRUE(manifest.intercept_namespaces[2].is_pattern);
494   EXPECT_FALSE(manifest.fallback_namespaces[0].is_pattern);
495   EXPECT_TRUE(manifest.fallback_namespaces[1].is_pattern);
496   EXPECT_FALSE(manifest.online_whitelist_namespaces[0].is_pattern);
497   EXPECT_TRUE(manifest.online_whitelist_namespaces[1].is_pattern);
498   EXPECT_EQ(
499       GURL("http://foo.com/*/intercept_pattern?query"),
500       manifest.intercept_namespaces[2].namespace_url);
501   EXPECT_EQ(
502       GURL("http://foo.com/pattern"),
503       manifest.intercept_namespaces[2].target_url);
504   EXPECT_EQ(
505       GURL("http://foo.com/fallback_pattern*"),
506       manifest.fallback_namespaces[1].namespace_url);
507   EXPECT_EQ(
508       GURL("http://foo.com/pattern"),
509       manifest.fallback_namespaces[1].target_url);
510   EXPECT_EQ(
511       GURL("http://foo.com/isPattern"),
512       manifest.online_whitelist_namespaces[0].namespace_url);
513   EXPECT_EQ(
514       GURL(),
515       manifest.online_whitelist_namespaces[0].target_url);
516   EXPECT_EQ(
517       GURL("http://foo.com/network_pattern*"),
518       manifest.online_whitelist_namespaces[1].namespace_url);
519   EXPECT_EQ(
520       GURL(),
521       manifest.online_whitelist_namespaces[1].target_url);
522 }
523 
524 }  // namespace content
525