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