| OLD | NEW | 
|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 <stddef.h> | 5 #include <stddef.h> | 
| 6 #include <stdint.h> | 6 #include <stdint.h> | 
| 7 | 7 | 
| 8 #include <map> | 8 #include <map> | 
| 9 #include <memory> | 9 #include <memory> | 
| 10 #include <utility> | 10 #include <utility> | 
| 11 | 11 | 
| 12 #include "base/bind.h" | 12 #include "base/bind.h" | 
| 13 #include "base/callback.h" | 13 #include "base/callback.h" | 
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" | 
|  | 15 #include "base/json/json_reader.h" | 
| 15 #include "base/macros.h" | 16 #include "base/macros.h" | 
| 16 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" | 
| 17 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" | 
| 18 #include "base/run_loop.h" | 19 #include "base/run_loop.h" | 
| 19 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" | 
| 20 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" | 
|  | 22 #include "base/strings/string_number_conversions.h" | 
| 21 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" | 
| 22 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" | 
| 23 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" | 
| 24 #include "base/time/time.h" | 26 #include "base/time/time.h" | 
| 25 #include "build/build_config.h" | 27 #include "build/build_config.h" | 
| 26 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 28 #include "content/browser/blob_storage/chrome_blob_storage_context.h" | 
| 27 #include "content/browser/cache_storage/cache_storage_cache.h" | 29 #include "content/browser/cache_storage/cache_storage_cache.h" | 
| 28 #include "content/browser/cache_storage/cache_storage_cache_handle.h" | 30 #include "content/browser/cache_storage/cache_storage_cache_handle.h" | 
| 29 #include "content/browser/cache_storage/cache_storage_context_impl.h" | 31 #include "content/browser/cache_storage/cache_storage_context_impl.h" | 
| 30 #include "content/browser/cache_storage/cache_storage_manager.h" | 32 #include "content/browser/cache_storage/cache_storage_manager.h" | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 45 #include "content/public/browser/browser_context.h" | 47 #include "content/public/browser/browser_context.h" | 
| 46 #include "content/public/browser/browser_thread.h" | 48 #include "content/public/browser/browser_thread.h" | 
| 47 #include "content/public/browser/content_browser_client.h" | 49 #include "content/public/browser/content_browser_client.h" | 
| 48 #include "content/public/browser/navigation_entry.h" | 50 #include "content/public/browser/navigation_entry.h" | 
| 49 #include "content/public/browser/render_process_host.h" | 51 #include "content/public/browser/render_process_host.h" | 
| 50 #include "content/public/browser/render_view_host.h" | 52 #include "content/public/browser/render_view_host.h" | 
| 51 #include "content/public/browser/ssl_status.h" | 53 #include "content/public/browser/ssl_status.h" | 
| 52 #include "content/public/browser/storage_partition.h" | 54 #include "content/public/browser/storage_partition.h" | 
| 53 #include "content/public/browser/web_contents.h" | 55 #include "content/public/browser/web_contents.h" | 
| 54 #include "content/public/common/content_client.h" | 56 #include "content/public/common/content_client.h" | 
|  | 57 #include "content/public/common/content_features.h" | 
| 55 #include "content/public/common/content_switches.h" | 58 #include "content/public/common/content_switches.h" | 
| 56 #include "content/public/common/referrer.h" | 59 #include "content/public/common/referrer.h" | 
| 57 #include "content/public/common/resource_type.h" | 60 #include "content/public/common/resource_type.h" | 
| 58 #include "content/public/common/web_preferences.h" | 61 #include "content/public/common/web_preferences.h" | 
| 59 #include "content/public/test/browser_test_utils.h" | 62 #include "content/public/test/browser_test_utils.h" | 
| 60 #include "content/public/test/content_browser_test.h" | 63 #include "content/public/test/content_browser_test.h" | 
| 61 #include "content/public/test/content_browser_test_utils.h" | 64 #include "content/public/test/content_browser_test_utils.h" | 
| 62 #include "content/shell/browser/shell.h" | 65 #include "content/shell/browser/shell.h" | 
| 63 #include "content/shell/browser/shell_content_browser_client.h" | 66 #include "content/shell/browser/shell_content_browser_client.h" | 
| 64 #include "content/test/test_content_browser_client.h" | 67 #include "content/test/test_content_browser_client.h" | 
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 327   else if (infos[index].active_version.version_id != | 330   else if (infos[index].active_version.version_id != | 
| 328            kInvalidServiceWorkerVersionId) | 331            kInvalidServiceWorkerVersionId) | 
| 329     version_id = infos[index].active_version.version_id; | 332     version_id = infos[index].active_version.version_id; | 
| 330   else | 333   else | 
| 331     return; | 334     return; | 
| 332 | 335 | 
| 333   ServiceWorkerVersion* version = wrapper->GetLiveVersion(version_id); | 336   ServiceWorkerVersion* version = wrapper->GetLiveVersion(version_id); | 
| 334   *num_resources = static_cast<int>(version->script_cache_map()->size()); | 337   *num_resources = static_cast<int>(version->script_cache_map()->size()); | 
| 335 } | 338 } | 
| 336 | 339 | 
|  | 340 void StoreString(std::string* result, | 
|  | 341                  const base::Closure& callback, | 
|  | 342                  const base::Value* value) { | 
|  | 343   value->GetAsString(result); | 
|  | 344   callback.Run(); | 
|  | 345 } | 
|  | 346 | 
|  | 347 int GetInt(const base::DictionaryValue& dict, base::StringPiece path) { | 
|  | 348   int out = 0; | 
|  | 349   EXPECT_TRUE(dict.GetInteger(path, &out)); | 
|  | 350   return out; | 
|  | 351 } | 
|  | 352 | 
|  | 353 std::string GetString(const base::DictionaryValue& dict, | 
|  | 354                       base::StringPiece path) { | 
|  | 355   std::string out; | 
|  | 356   EXPECT_TRUE(dict.GetString(path, &out)); | 
|  | 357   return out; | 
|  | 358 } | 
|  | 359 | 
|  | 360 bool GetBoolean(const base::DictionaryValue& dict, base::StringPiece path) { | 
|  | 361   bool out = false; | 
|  | 362   EXPECT_TRUE(dict.GetBoolean(path, &out)); | 
|  | 363   return out; | 
|  | 364 } | 
|  | 365 | 
|  | 366 bool CheckHeader(const base::DictionaryValue& dict, | 
|  | 367                  base::StringPiece header_name, | 
|  | 368                  base::StringPiece header_value) { | 
|  | 369   const base::ListValue* headers = nullptr; | 
|  | 370   EXPECT_TRUE(dict.GetList("headers", &headers)); | 
|  | 371   for (size_t i = 0; i < headers->GetSize(); ++i) { | 
|  | 372     const base::ListValue* name_value_pair = nullptr; | 
|  | 373     EXPECT_TRUE(headers->GetList(i, &name_value_pair)); | 
|  | 374     EXPECT_EQ(2u, name_value_pair->GetSize()); | 
|  | 375     std::string name; | 
|  | 376     EXPECT_TRUE(name_value_pair->GetString(0, &name)); | 
|  | 377     std::string value; | 
|  | 378     EXPECT_TRUE(name_value_pair->GetString(1, &value)); | 
|  | 379     if (name == header_name && value == header_value) | 
|  | 380       return true; | 
|  | 381   } | 
|  | 382   return false; | 
|  | 383 } | 
|  | 384 | 
| 337 }  // namespace | 385 }  // namespace | 
| 338 | 386 | 
| 339 class ServiceWorkerBrowserTest : public testing::WithParamInterface<bool>, | 387 class ServiceWorkerBrowserTest : public testing::WithParamInterface<bool>, | 
| 340                                  public ContentBrowserTest { | 388                                  public ContentBrowserTest { | 
| 341  protected: | 389  protected: | 
| 342   using self = ServiceWorkerBrowserTest; | 390   using self = ServiceWorkerBrowserTest; | 
| 343 | 391 | 
| 344   void SetUp() override { | 392   void SetUp() override { | 
| 345     is_mojo_enabled_ = GetParam(); | 393     is_mojo_enabled_ = GetParam(); | 
| 346     if (is_mojo_enabled()) { | 394     if (is_mojo_enabled()) { | 
| (...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1353 | 1401 | 
| 1354   shell()->Close(); | 1402   shell()->Close(); | 
| 1355 | 1403 | 
| 1356   base::RunLoop run_loop; | 1404   base::RunLoop run_loop; | 
| 1357   public_context()->UnregisterServiceWorker( | 1405   public_context()->UnregisterServiceWorker( | 
| 1358       embedded_test_server()->GetURL(kPageUrl), | 1406       embedded_test_server()->GetURL(kPageUrl), | 
| 1359       base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); | 1407       base::Bind(&ExpectResultAndRun, true, run_loop.QuitClosure())); | 
| 1360   run_loop.Run(); | 1408   run_loop.Run(); | 
| 1361 } | 1409 } | 
| 1362 | 1410 | 
|  | 1411 class ServiceWorkerNavigationPreloadTest : public ServiceWorkerBrowserTest { | 
|  | 1412  public: | 
|  | 1413   using self = ServiceWorkerNavigationPreloadTest; | 
|  | 1414 | 
|  | 1415   ~ServiceWorkerNavigationPreloadTest() override {} | 
|  | 1416 | 
|  | 1417   void SetUpCommandLine(base::CommandLine* command_line) override { | 
|  | 1418     command_line->AppendSwitchASCII( | 
|  | 1419         switches::kEnableFeatures, | 
|  | 1420         features::kServiceWorkerNavigationPreload.name); | 
|  | 1421   } | 
|  | 1422 | 
|  | 1423  protected: | 
|  | 1424   void SetupForNavigationPreloadTest(const GURL& scope, | 
|  | 1425                                      const GURL& worker_url) { | 
|  | 1426     scoped_refptr<WorkerActivatedObserver> observer = | 
|  | 1427         new WorkerActivatedObserver(wrapper()); | 
|  | 1428     observer->Init(); | 
|  | 1429     public_context()->RegisterServiceWorker( | 
|  | 1430         scope, worker_url, | 
|  | 1431         base::Bind(&ExpectResultAndRun, true, base::Bind(&base::DoNothing))); | 
|  | 1432     observer->Wait(); | 
|  | 1433 | 
|  | 1434     RunOnIOThread(base::Bind(&self::EnableNavigationPreloadOnIO, | 
|  | 1435                              base::Unretained(this), scope)); | 
|  | 1436 | 
|  | 1437     embedded_test_server()->RegisterRequestMonitor( | 
|  | 1438         base::Bind(&self::MonitorRequestHandler, base::Unretained(this))); | 
|  | 1439   } | 
|  | 1440 | 
|  | 1441   void RegisterStaticFile(const GURL& url, | 
|  | 1442                           const std::string& content, | 
|  | 1443                           const std::string& content_type) { | 
|  | 1444     embedded_test_server()->RegisterRequestHandler( | 
|  | 1445         base::Bind(&self::StaticRequestHandler, base::Unretained(this), url, | 
|  | 1446                    content, content_type)); | 
|  | 1447   } | 
|  | 1448 | 
|  | 1449   void RegisterCustomResponse(const GURL& url, const std::string& response) { | 
|  | 1450     embedded_test_server()->RegisterRequestHandler(base::Bind( | 
|  | 1451         &self::CustomRequestHandler, base::Unretained(this), url, response)); | 
|  | 1452   } | 
|  | 1453 | 
|  | 1454   int GetRequestCount(const std::string& relative_url) const { | 
|  | 1455     int count = 0; | 
|  | 1456     for (const auto& request : request_log_) { | 
|  | 1457       if (request == relative_url) | 
|  | 1458         ++count; | 
|  | 1459     } | 
|  | 1460     return count; | 
|  | 1461   } | 
|  | 1462 | 
|  | 1463   std::string GetTextContent() { | 
|  | 1464     base::RunLoop run_loop; | 
|  | 1465     std::string text_content; | 
|  | 1466     shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests( | 
|  | 1467         base::ASCIIToUTF16("document.body.textContent;"), | 
|  | 1468         base::Bind(&StoreString, &text_content, run_loop.QuitClosure())); | 
|  | 1469     run_loop.Run(); | 
|  | 1470     return text_content; | 
|  | 1471   } | 
|  | 1472 | 
|  | 1473   static const char kPreloadResponseTestScript[]; | 
|  | 1474 | 
|  | 1475  private: | 
|  | 1476   class CustomResponse : public net::test_server::HttpResponse { | 
|  | 1477    public: | 
|  | 1478     CustomResponse(const std::string& response) : response_(response) {} | 
|  | 1479     ~CustomResponse() override {} | 
|  | 1480 | 
|  | 1481     void SendResponse( | 
|  | 1482         const net::test_server::SendBytesCallback& send, | 
|  | 1483         const net::test_server::SendCompleteCallback& done) override { | 
|  | 1484       send.Run(response_, done); | 
|  | 1485     } | 
|  | 1486 | 
|  | 1487    private: | 
|  | 1488     const std::string response_; | 
|  | 1489 | 
|  | 1490     DISALLOW_COPY_AND_ASSIGN(CustomResponse); | 
|  | 1491   }; | 
|  | 1492 | 
|  | 1493   void EnableNavigationPreloadOnIO(const GURL& scope, | 
|  | 1494                                    const base::Closure& continuation) { | 
|  | 1495     wrapper()->FindReadyRegistrationForDocument( | 
|  | 1496         scope, base::Bind(&self::DidFindRegistrationForEnableNavigationPreload, | 
|  | 1497                           base::Unretained(this), continuation)); | 
|  | 1498   } | 
|  | 1499 | 
|  | 1500   void DidFindRegistrationForEnableNavigationPreload( | 
|  | 1501       const base::Closure& continuation, | 
|  | 1502       ServiceWorkerStatusCode status, | 
|  | 1503       scoped_refptr<ServiceWorkerRegistration> registration) { | 
|  | 1504     EXPECT_EQ(SERVICE_WORKER_OK, status); | 
|  | 1505     ASSERT_TRUE(registration->active_version()); | 
|  | 1506     registration->active_version()->set_navigation_preload_enabled(true); | 
|  | 1507     continuation.Run(); | 
|  | 1508   } | 
|  | 1509 | 
|  | 1510   std::unique_ptr<net::test_server::HttpResponse> StaticRequestHandler( | 
|  | 1511       const GURL& url, | 
|  | 1512       const std::string& content, | 
|  | 1513       const std::string& content_type, | 
|  | 1514       const net::test_server::HttpRequest& request) const { | 
|  | 1515     const GURL absolute_url = | 
|  | 1516         embedded_test_server()->GetURL(request.relative_url); | 
|  | 1517     if (absolute_url != url) | 
|  | 1518       return std::unique_ptr<net::test_server::HttpResponse>(); | 
|  | 1519 | 
|  | 1520     std::unique_ptr<net::test_server::BasicHttpResponse> http_response( | 
|  | 1521         base::MakeUnique<net::test_server::BasicHttpResponse>()); | 
|  | 1522     http_response->set_code(net::HTTP_OK); | 
|  | 1523     http_response->set_content(content); | 
|  | 1524     http_response->set_content_type(content_type); | 
|  | 1525     return std::move(http_response); | 
|  | 1526   } | 
|  | 1527 | 
|  | 1528   std::unique_ptr<net::test_server::HttpResponse> CustomRequestHandler( | 
|  | 1529       const GURL& url, | 
|  | 1530       const std::string& response, | 
|  | 1531       const net::test_server::HttpRequest& request) const { | 
|  | 1532     const GURL absolute_url = | 
|  | 1533         embedded_test_server()->GetURL(request.relative_url); | 
|  | 1534     if (absolute_url != url) | 
|  | 1535       return std::unique_ptr<net::test_server::HttpResponse>(); | 
|  | 1536 | 
|  | 1537     return base::MakeUnique<CustomResponse>(response); | 
|  | 1538   } | 
|  | 1539 | 
|  | 1540   void MonitorRequestHandler(const net::test_server::HttpRequest& request) { | 
|  | 1541     request_log_.push_back(request.relative_url); | 
|  | 1542   } | 
|  | 1543 | 
|  | 1544   std::vector<std::string> request_log_; | 
|  | 1545 }; | 
|  | 1546 | 
|  | 1547 const char ServiceWorkerNavigationPreloadTest::kPreloadResponseTestScript[] = | 
|  | 1548     "var preload_resolve;\n" | 
|  | 1549     "var preload_promise = new Promise(r => { preload_resolve = r; });\n" | 
|  | 1550     "self.addEventListener('fetch', event => {\n" | 
|  | 1551     "    event.waitUntil(event.navigationPreload.then(\n" | 
|  | 1552     "        r => {\n" | 
|  | 1553     "          var info = {};\n" | 
|  | 1554     "          info.type = r.type;\n" | 
|  | 1555     "          info.url = r.url;\n" | 
|  | 1556     "          info.status = r.status;\n" | 
|  | 1557     "          info.ok = r.ok;\n" | 
|  | 1558     "          info.statusText = r.statusText;\n" | 
|  | 1559     "          info.headers = [];\n" | 
|  | 1560     "          r.headers.forEach((v, n) => { info.headers.push([n,v]); });\n" | 
|  | 1561     "          preload_resolve({result: 'RESOLVED',\n" | 
|  | 1562     "                           info: JSON.stringify(info)}); },\n" | 
|  | 1563     "        e => { preload_resolve({result: 'REJECTED',\n" | 
|  | 1564     "                                info: e.toString()}); }));\n" | 
|  | 1565     "    event.respondWith(\n" | 
|  | 1566     "        new Response(\n" | 
|  | 1567     "            '<title>WAITING</title><script>\\n' +\n" | 
|  | 1568     "            'var channel = new MessageChannel();\\n' +\n" | 
|  | 1569     "            'channel.port1.onmessage = e => {\\n' +\n" | 
|  | 1570     "            '    var div = document.createElement(\\'div\\');\\n' +\n" | 
|  | 1571     "            '    div.appendChild(' +\n" | 
|  | 1572     "            '        document.createTextNode(e.data.info));\\n' +\n" | 
|  | 1573     "            '    document.body.appendChild(div);\\n' +\n" | 
|  | 1574     "            '    document.title = e.data.result;\\n' +\n" | 
|  | 1575     "            '  };\\n' +\n" | 
|  | 1576     "            'navigator.serviceWorker.controller.postMessage(\\n' +\n" | 
|  | 1577     "            '    {}, [channel.port2]);\\n' +\n" | 
|  | 1578     "            '</script>'," | 
|  | 1579     "            {headers: [['content-type', 'text/html']]}));\n" | 
|  | 1580     "  });\n" | 
|  | 1581     "self.addEventListener('message', event => {\n" | 
|  | 1582     "    event.waitUntil(\n" | 
|  | 1583     "        preload_promise.then(\n" | 
|  | 1584     "            result => event.ports[0].postMessage(result)));\n" | 
|  | 1585     "  });"; | 
|  | 1586 | 
|  | 1587 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, NetworkFallback) { | 
|  | 1588   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1589   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1590   const char kPage[] = "<title>PASS</title>Hello world."; | 
|  | 1591   const char kScript[] = | 
|  | 1592       "self.addEventListener('fetch', event => {\n" | 
|  | 1593       "    // Do nothing.\n" | 
|  | 1594       "  });"; | 
|  | 1595   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1596   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1597   RegisterStaticFile(page_url, kPage, "text/html"); | 
|  | 1598   RegisterStaticFile(worker_url, kScript, "text/javascript"); | 
|  | 1599 | 
|  | 1600   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1601 | 
|  | 1602   const base::string16 title = base::ASCIIToUTF16("PASS"); | 
|  | 1603   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1604   NavigateToURL(shell(), page_url); | 
|  | 1605   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1606   EXPECT_EQ("Hello world.", GetTextContent()); | 
|  | 1607 | 
|  | 1608   // The page request must be sent twice. Once for navigation preload, and once | 
|  | 1609   // for fallback since respondWith wasn't used. | 
|  | 1610   EXPECT_EQ(2, GetRequestCount(kPageUrl)); | 
|  | 1611   // TODO(horo): Check "Service-Worker-Navigation-Preload" header. | 
|  | 1612   // See: https://github.com/w3c/ServiceWorker/issues/920#issuecomment-251150270 | 
|  | 1613 } | 
|  | 1614 | 
|  | 1615 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, | 
|  | 1616                        RespondWithNavigationPreload) { | 
|  | 1617   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1618   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1619   const char kPage[] = "<title>PASS</title>Hello world."; | 
|  | 1620   const char kScript[] = | 
|  | 1621       "self.addEventListener('fetch', event => {\n" | 
|  | 1622       "    if (!event.navigationPreload) {\n" | 
|  | 1623       "      event.respondWith(\n" | 
|  | 1624       "          new Response('<title>ERROR</title>'," | 
|  | 1625       "                       {headers: [['content-type', 'text/html']]}));\n" | 
|  | 1626       "      return;\n" | 
|  | 1627       "    }\n" | 
|  | 1628       "    event.respondWith(event.navigationPreload);\n" | 
|  | 1629       "  });"; | 
|  | 1630   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1631   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1632   RegisterStaticFile(page_url, kPage, "text/html"); | 
|  | 1633   RegisterStaticFile(worker_url, kScript, "text/javascript"); | 
|  | 1634 | 
|  | 1635   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1636 | 
|  | 1637   const base::string16 title = base::ASCIIToUTF16("PASS"); | 
|  | 1638   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1639   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("ERROR")); | 
|  | 1640   NavigateToURL(shell(), page_url); | 
|  | 1641   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1642   EXPECT_EQ("Hello world.", GetTextContent()); | 
|  | 1643 | 
|  | 1644   // The page request must be sent only once, since the worker responded with | 
|  | 1645   // the navigation preload response | 
|  | 1646   EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 
|  | 1647   // TODO(horo): Check "Service-Worker-Navigation-Preload" header. | 
|  | 1648   // See: https://github.com/w3c/ServiceWorker/issues/920#issuecomment-251150270 | 
|  | 1649 } | 
|  | 1650 | 
|  | 1651 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, GetResponseText) { | 
|  | 1652   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1653   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1654   const char kPage[] = "<title>PASS</title>Hello world."; | 
|  | 1655   const char kScript[] = | 
|  | 1656       "self.addEventListener('fetch', event => {\n" | 
|  | 1657       "    event.respondWith(\n" | 
|  | 1658       "        event.navigationPreload\n" | 
|  | 1659       "          .then(response => response.text())\n" | 
|  | 1660       "          .then(text =>\n" | 
|  | 1661       "                  new Response(\n" | 
|  | 1662       "                      text,\n" | 
|  | 1663       "                      {headers: [['content-type', 'text/html']]})));\n" | 
|  | 1664       "  });"; | 
|  | 1665   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1666   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1667   RegisterStaticFile(page_url, kPage, "text/html"); | 
|  | 1668   RegisterStaticFile(worker_url, kScript, "text/javascript"); | 
|  | 1669 | 
|  | 1670   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1671 | 
|  | 1672   const base::string16 title = base::ASCIIToUTF16("PASS"); | 
|  | 1673   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1674   NavigateToURL(shell(), page_url); | 
|  | 1675   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1676   EXPECT_EQ("Hello world.", GetTextContent()); | 
|  | 1677 | 
|  | 1678   // The page request must be sent only once, since the worker responded with | 
|  | 1679   // "Hello world". | 
|  | 1680   EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 
|  | 1681 } | 
|  | 1682 | 
|  | 1683 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, | 
|  | 1684                        AbortPreloadRequest) { | 
|  | 1685   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1686   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1687   const char kPage[] = "<title>ERROR</title>Hello world."; | 
|  | 1688   // In this script, event.navigationPreload is not guarded by event.waitUntil. | 
|  | 1689   // So the preload request should be canceled, when the fetch event handler | 
|  | 1690   // has been executed. | 
|  | 1691   const char kScript[] = | 
|  | 1692       "var preload_resolve;\n" | 
|  | 1693       "var preload_promise = new Promise(r => { preload_resolve = r; });\n" | 
|  | 1694       "self.addEventListener('fetch', event => {\n" | 
|  | 1695       "    event.navigationPreload.then(\n" | 
|  | 1696       "        _ => { preload_resolve({result: 'RESOLVED',\n" | 
|  | 1697       "                                info: 'Preload resolved.'}); },\n" | 
|  | 1698       "        e => { preload_resolve({result: 'REJECTED',\n" | 
|  | 1699       "                                info: e.toString()}); });\n" | 
|  | 1700       "    event.respondWith(\n" | 
|  | 1701       "        new Response(\n" | 
|  | 1702       "            '<title>WAITING</title><script>\\n' +\n" | 
|  | 1703       "            'var channel = new MessageChannel();\\n' +\n" | 
|  | 1704       "            'channel.port1.onmessage = e => {\\n' +\n" | 
|  | 1705       "            '    var div = document.createElement(\\'div\\');\\n' +\n" | 
|  | 1706       "            '    div.appendChild(' +\n" | 
|  | 1707       "            '        document.createTextNode(e.data.info));\\n' +\n" | 
|  | 1708       "            '    document.body.appendChild(div);\\n' +\n" | 
|  | 1709       "            '    document.title = e.data.result;\\n' +\n" | 
|  | 1710       "            '  };\\n' +\n" | 
|  | 1711       "            'navigator.serviceWorker.controller.postMessage(\\n' +\n" | 
|  | 1712       "            '    {}, [channel.port2]);\\n' +\n" | 
|  | 1713       "            '</script>'," | 
|  | 1714       "            {headers: [['content-type', 'text/html']]}));\n" | 
|  | 1715       "  });\n" | 
|  | 1716       "self.addEventListener('message', event => {\n" | 
|  | 1717       "    event.waitUntil(\n" | 
|  | 1718       "        preload_promise.then(\n" | 
|  | 1719       "            result => event.ports[0].postMessage(result)));\n" | 
|  | 1720       "  });"; | 
|  | 1721   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1722   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1723   RegisterStaticFile(page_url, kPage, "text/html"); | 
|  | 1724   RegisterStaticFile(worker_url, kScript, "text/javascript"); | 
|  | 1725 | 
|  | 1726   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1727 | 
|  | 1728   const base::string16 title = base::ASCIIToUTF16("REJECTED"); | 
|  | 1729   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1730   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("RESOLVED")); | 
|  | 1731   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("ERROR")); | 
|  | 1732   NavigateToURL(shell(), page_url); | 
|  | 1733   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1734 | 
|  | 1735   EXPECT_EQ( | 
|  | 1736       "AbortError: Service Worker navigation preload aborted. Need to guard " | 
|  | 1737       "with respondWith or waitUntil.", | 
|  | 1738       GetTextContent()); | 
|  | 1739 } | 
|  | 1740 | 
|  | 1741 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, NetworkError) { | 
|  | 1742   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1743   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1744   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1745   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1746   RegisterStaticFile(worker_url, kPreloadResponseTestScript, "text/javascript"); | 
|  | 1747 | 
|  | 1748   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1749 | 
|  | 1750   EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); | 
|  | 1751 | 
|  | 1752   const base::string16 title = base::ASCIIToUTF16("REJECTED"); | 
|  | 1753   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1754   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("RESOLVED")); | 
|  | 1755   NavigateToURL(shell(), page_url); | 
|  | 1756   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1757   EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 
|  | 1758             GetTextContent()); | 
|  | 1759 } | 
|  | 1760 | 
|  | 1761 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, | 
|  | 1762                        PreloadHeadersSimple) { | 
|  | 1763   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1764   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1765   const char kPage[] = "<title>ERROR</title>Hello world."; | 
|  | 1766   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1767   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1768   RegisterStaticFile(page_url, kPage, "text/html"); | 
|  | 1769   RegisterStaticFile(worker_url, kPreloadResponseTestScript, "text/javascript"); | 
|  | 1770 | 
|  | 1771   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1772 | 
|  | 1773   const base::string16 title = base::ASCIIToUTF16("RESOLVED"); | 
|  | 1774   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1775   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("REJECTED")); | 
|  | 1776   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("ERROR")); | 
|  | 1777   NavigateToURL(shell(), page_url); | 
|  | 1778   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1779 | 
|  | 1780   // The page request must be sent only once, since the worker responded with | 
|  | 1781   // a generated Response. | 
|  | 1782   EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 
|  | 1783   std::unique_ptr<base::Value> result = | 
|  | 1784       base::JSONReader::Read(GetTextContent()); | 
|  | 1785   base::DictionaryValue* dict = nullptr; | 
|  | 1786   ASSERT_TRUE(result->GetAsDictionary(&dict)); | 
|  | 1787   EXPECT_EQ("basic", GetString(*dict, "type")); | 
|  | 1788   EXPECT_EQ(page_url, GURL(GetString(*dict, "url"))); | 
|  | 1789   EXPECT_EQ(200, GetInt(*dict, "status")); | 
|  | 1790   EXPECT_EQ(true, GetBoolean(*dict, "ok")); | 
|  | 1791   EXPECT_EQ("OK", GetString(*dict, "statusText")); | 
|  | 1792   EXPECT_TRUE(CheckHeader(*dict, "content-type", "text/html")); | 
|  | 1793   EXPECT_TRUE(CheckHeader(*dict, "content-length", | 
|  | 1794                           base::IntToString(sizeof(kPage) - 1))); | 
|  | 1795 } | 
|  | 1796 | 
|  | 1797 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, | 
|  | 1798                        PreloadHeadersCustom) { | 
|  | 1799   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1800   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1801   const char kPageResponse[] = | 
|  | 1802       "HTTP/1.1 201 HELLOWORLD\r\n" | 
|  | 1803       "Connection: close\r\n" | 
|  | 1804       "Content-Length: 32\r\n" | 
|  | 1805       "Content-Type: text/html\r\n" | 
|  | 1806       "Custom-Header: pen pineapple\r\n" | 
|  | 1807       "Custom-Header: apple pen\r\n" | 
|  | 1808       "Set-Cookie: COOKIE1\r\n" | 
|  | 1809       "Set-Cookie2: COOKIE2\r\n" | 
|  | 1810       "\r\n" | 
|  | 1811       "<title>ERROR</title>Hello world."; | 
|  | 1812   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1813   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1814   RegisterCustomResponse(page_url, kPageResponse); | 
|  | 1815   RegisterStaticFile(worker_url, kPreloadResponseTestScript, "text/javascript"); | 
|  | 1816 | 
|  | 1817   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1818 | 
|  | 1819   const base::string16 title = base::ASCIIToUTF16("RESOLVED"); | 
|  | 1820   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1821   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("REJECTED")); | 
|  | 1822   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("ERROR")); | 
|  | 1823   NavigateToURL(shell(), page_url); | 
|  | 1824   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1825 | 
|  | 1826   // The page request must be sent only once, since the worker responded with | 
|  | 1827   // a generated Response. | 
|  | 1828   EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 
|  | 1829   std::unique_ptr<base::Value> result = | 
|  | 1830       base::JSONReader::Read(GetTextContent()); | 
|  | 1831   base::DictionaryValue* dict = nullptr; | 
|  | 1832   ASSERT_TRUE(result->GetAsDictionary(&dict)); | 
|  | 1833   EXPECT_EQ("basic", GetString(*dict, "type")); | 
|  | 1834   EXPECT_EQ(page_url, GURL(GetString(*dict, "url"))); | 
|  | 1835   EXPECT_EQ(201, GetInt(*dict, "status")); | 
|  | 1836   EXPECT_EQ(true, GetBoolean(*dict, "ok")); | 
|  | 1837   EXPECT_EQ("HELLOWORLD", GetString(*dict, "statusText")); | 
|  | 1838   EXPECT_TRUE(CheckHeader(*dict, "content-type", "text/html")); | 
|  | 1839   EXPECT_TRUE(CheckHeader(*dict, "content-length", "32")); | 
|  | 1840   EXPECT_TRUE(CheckHeader(*dict, "custom-header", "pen pineapple, apple pen")); | 
|  | 1841   // The forbidden response headers (Set-Cookie, Set-Cookie2) must be removed. | 
|  | 1842   EXPECT_FALSE(dict->HasKey("set-cookie")); | 
|  | 1843   EXPECT_FALSE(dict->HasKey("set-cookie2")); | 
|  | 1844 } | 
|  | 1845 | 
|  | 1846 IN_PROC_BROWSER_TEST_P(ServiceWorkerNavigationPreloadTest, RejectRedirects) { | 
|  | 1847   const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 
|  | 1848   const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 
|  | 1849   const char kRedirectedPageUrl[] = | 
|  | 1850       "/service_worker/navigation_preload_redirected.html"; | 
|  | 1851   const char kPageResponse[] = | 
|  | 1852       "HTTP/1.1 302 Found\r\n" | 
|  | 1853       "Connection: close\r\n" | 
|  | 1854       "Location: /service_worker/navigation_preload_redirected.html\r\n" | 
|  | 1855       "\r\n"; | 
|  | 1856   const char kRedirectedPage[] = "<title>ERROR</title>Redirected page."; | 
|  | 1857   const GURL redirecred_page_url = | 
|  | 1858       embedded_test_server()->GetURL(kRedirectedPageUrl); | 
|  | 1859   const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 
|  | 1860   const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 
|  | 1861   RegisterCustomResponse(page_url, kPageResponse); | 
|  | 1862   RegisterStaticFile(worker_url, kPreloadResponseTestScript, "text/javascript"); | 
|  | 1863   RegisterStaticFile(redirecred_page_url, kRedirectedPage, "text/html"); | 
|  | 1864 | 
|  | 1865   SetupForNavigationPreloadTest(page_url, worker_url); | 
|  | 1866 | 
|  | 1867   const base::string16 title = base::ASCIIToUTF16("REJECTED"); | 
|  | 1868   TitleWatcher title_watcher(shell()->web_contents(), title); | 
|  | 1869   title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("RESOLVED")); | 
|  | 1870   NavigateToURL(shell(), page_url); | 
|  | 1871   EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 
|  | 1872 | 
|  | 1873   // The page request must be sent only once, since the worker responded with | 
|  | 1874   // a generated Response. | 
|  | 1875   EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 
|  | 1876   // The redirected request must not be sent. | 
|  | 1877   EXPECT_EQ(0, GetRequestCount(kRedirectedPageUrl)); | 
|  | 1878   // TODO(horo): When MojoAsyncResourceHandler will support redirection, we | 
|  | 1879   // shold provide more specific error message. | 
|  | 1880   EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 
|  | 1881             GetTextContent()); | 
|  | 1882 } | 
|  | 1883 | 
| 1363 // Flaky on Win/Mac: http://crbug.com/533631 | 1884 // Flaky on Win/Mac: http://crbug.com/533631 | 
| 1364 #if defined(OS_WIN) || defined(OS_MACOSX) | 1885 #if defined(OS_WIN) || defined(OS_MACOSX) | 
| 1365 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure DISABLED_ResponseFr
      omHTTPSServiceWorkerIsMarkedAsSecure | 1886 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure DISABLED_ResponseFr
      omHTTPSServiceWorkerIsMarkedAsSecure | 
| 1366 #else | 1887 #else | 
| 1367 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure ResponseFromHTTPSSe
      rviceWorkerIsMarkedAsSecure | 1888 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure ResponseFromHTTPSSe
      rviceWorkerIsMarkedAsSecure | 
| 1368 #endif | 1889 #endif | 
| 1369 IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, | 1890 IN_PROC_BROWSER_TEST_P(ServiceWorkerBrowserTest, | 
| 1370                        MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure) { | 1891                        MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure) { | 
| 1371   const char kPageUrl[] = "/service_worker/fetch_event_blob.html"; | 1892   const char kPageUrl[] = "/service_worker/fetch_event_blob.html"; | 
| 1372   const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; | 1893   const char kWorkerUrl[] = "/service_worker/fetch_event_blob.js"; | 
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2052 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2573 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2053                         ServiceWorkerVersionBrowserV8CacheTest, | 2574                         ServiceWorkerVersionBrowserV8CacheTest, | 
| 2054                         ::testing::Values(true, false)); | 2575                         ::testing::Values(true, false)); | 
| 2055 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2576 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2056                         ServiceWorkerVersionBrowserTest, | 2577                         ServiceWorkerVersionBrowserTest, | 
| 2057                         ::testing::Values(true, false)); | 2578                         ::testing::Values(true, false)); | 
| 2058 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2579 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2059                         ServiceWorkerBlackBoxBrowserTest, | 2580                         ServiceWorkerBlackBoxBrowserTest, | 
| 2060                         ::testing::Values(true, false)); | 2581                         ::testing::Values(true, false)); | 
| 2061 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2582 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
|  | 2583                         ServiceWorkerNavigationPreloadTest, | 
|  | 2584                         ::testing::Values(true, false)); | 
|  | 2585 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2062                         ServiceWorkerV8CacheStrategiesTest, | 2586                         ServiceWorkerV8CacheStrategiesTest, | 
| 2063                         ::testing::Values(true, false)); | 2587                         ::testing::Values(true, false)); | 
| 2064 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2588 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2065                         ServiceWorkerV8CacheStrategiesNoneTest, | 2589                         ServiceWorkerV8CacheStrategiesNoneTest, | 
| 2066                         ::testing::Values(true, false)); | 2590                         ::testing::Values(true, false)); | 
| 2067 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2591 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2068                         ServiceWorkerV8CacheStrategiesNormalTest, | 2592                         ServiceWorkerV8CacheStrategiesNormalTest, | 
| 2069                         ::testing::Values(true, false)); | 2593                         ::testing::Values(true, false)); | 
| 2070 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2594 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2071                         ServiceWorkerV8CacheStrategiesAggressiveTest, | 2595                         ServiceWorkerV8CacheStrategiesAggressiveTest, | 
| 2072                         ::testing::Values(true, false)); | 2596                         ::testing::Values(true, false)); | 
| 2073 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 2597 INSTANTIATE_TEST_CASE_P(ServiceWorkerBrowserTest, | 
| 2074                         ServiceWorkerDisableWebSecurityTest, | 2598                         ServiceWorkerDisableWebSecurityTest, | 
| 2075                         ::testing::Values(true, false)); | 2599                         ::testing::Values(true, false)); | 
| 2076 | 2600 | 
| 2077 }  // namespace content | 2601 }  // namespace content | 
| OLD | NEW | 
|---|