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 |