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