| 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> |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 net::HttpResponseInfo info; | 408 net::HttpResponseInfo info; |
| 409 const char data[] = | 409 const char data[] = |
| 410 "HTTP/1.1 200 OK\0" | 410 "HTTP/1.1 200 OK\0" |
| 411 "Content-Type: application/javascript\0" | 411 "Content-Type: application/javascript\0" |
| 412 "\0"; | 412 "\0"; |
| 413 info.headers = | 413 info.headers = |
| 414 new net::HttpResponseHeaders(std::string(data, arraysize(data))); | 414 new net::HttpResponseHeaders(std::string(data, arraysize(data))); |
| 415 return info; | 415 return info; |
| 416 } | 416 } |
| 417 | 417 |
| 418 const std::string kNavigationPreloadAbortError = |
| 419 "The service worker navigation preload request was cancelled before " |
| 420 "'preloadResponse' settled. If you intend to use 'preloadResponse', use " |
| 421 "waitUntil() or respondWith() to wait for the promise to settle."; |
| 422 const std::string kNavigationPreloadNetworkError = |
| 423 "The service worker navigation preload request failed with a network " |
| 424 "error."; |
| 425 |
| 418 } // namespace | 426 } // namespace |
| 419 | 427 |
| 420 class ServiceWorkerBrowserTest : public ContentBrowserTest { | 428 class ServiceWorkerBrowserTest : public ContentBrowserTest { |
| 421 protected: | 429 protected: |
| 422 using self = ServiceWorkerBrowserTest; | 430 using self = ServiceWorkerBrowserTest; |
| 423 | 431 |
| 424 void SetUpOnMainThread() override { | 432 void SetUpOnMainThread() override { |
| 425 ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); | 433 ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); |
| 426 StoragePartition* partition = BrowserContext::GetDefaultStoragePartition( | 434 StoragePartition* partition = BrowserContext::GetDefaultStoragePartition( |
| 427 shell()->web_contents()->GetBrowserContext()); | 435 shell()->web_contents()->GetBrowserContext()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 if (!quit_.is_null() && messages_.size() == expected_message_count_) | 511 if (!quit_.is_null() && messages_.size() == expected_message_count_) |
| 504 quit_.Run(); | 512 quit_.Run(); |
| 505 } | 513 } |
| 506 | 514 |
| 507 // These parameters must be accessed on the UI thread. | 515 // These parameters must be accessed on the UI thread. |
| 508 std::vector<base::string16> messages_; | 516 std::vector<base::string16> messages_; |
| 509 size_t expected_message_count_ = 0; | 517 size_t expected_message_count_ = 0; |
| 510 base::Closure quit_; | 518 base::Closure quit_; |
| 511 }; | 519 }; |
| 512 | 520 |
| 521 // Listens to console messages on ServiceWorkerContextWrapper. |
| 522 class ConsoleMessageContextObserver |
| 523 : public ServiceWorkerContextObserver, |
| 524 public base::RefCountedThreadSafe<ConsoleMessageContextObserver> { |
| 525 public: |
| 526 explicit ConsoleMessageContextObserver(ServiceWorkerContextWrapper* context) |
| 527 : context_(context) {} |
| 528 void Init() { context_->AddObserver(this); } |
| 529 |
| 530 // ServiceWorkerContextObserver overrides. |
| 531 void OnReportConsoleMessage(int64_t version_id, |
| 532 int process_id, |
| 533 int thread_id, |
| 534 const ConsoleMessage& console_message) override { |
| 535 messages_.push_back(console_message.message); |
| 536 if (messages_.size() == expected_message_count_) { |
| 537 run_loop_.Quit(); |
| 538 } |
| 539 } |
| 540 |
| 541 void WaitForConsoleMessages(size_t expected_message_count) { |
| 542 if (messages_.size() >= expected_message_count) { |
| 543 context_->RemoveObserver(this); |
| 544 return; |
| 545 } |
| 546 |
| 547 expected_message_count_ = expected_message_count; |
| 548 run_loop_.Run(); |
| 549 ASSERT_EQ(messages_.size(), expected_message_count); |
| 550 context_->RemoveObserver(this); |
| 551 } |
| 552 |
| 553 const std::vector<base::string16>& messages() const { return messages_; } |
| 554 |
| 555 private: |
| 556 friend class base::RefCountedThreadSafe<ConsoleMessageContextObserver>; |
| 557 ~ConsoleMessageContextObserver() override {} |
| 558 |
| 559 std::vector<base::string16> messages_; |
| 560 size_t expected_message_count_ = 0; |
| 561 base::RunLoop run_loop_; |
| 562 ServiceWorkerContextWrapper* context_; |
| 563 |
| 564 DISALLOW_COPY_AND_ASSIGN(ConsoleMessageContextObserver); |
| 565 }; |
| 566 |
| 513 class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { | 567 class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { |
| 514 public: | 568 public: |
| 515 using self = ServiceWorkerVersionBrowserTest; | 569 using self = ServiceWorkerVersionBrowserTest; |
| 516 | 570 |
| 517 ~ServiceWorkerVersionBrowserTest() override {} | 571 ~ServiceWorkerVersionBrowserTest() override {} |
| 518 | 572 |
| 519 void TearDownOnIOThread() override { | 573 void TearDownOnIOThread() override { |
| 520 registration_ = NULL; | 574 registration_ = NULL; |
| 521 version_ = NULL; | 575 version_ = NULL; |
| 522 } | 576 } |
| (...skipping 1366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 RegisterStaticFile( | 1943 RegisterStaticFile( |
| 1890 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, | 1944 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, |
| 1891 "text/javascript"); | 1945 "text/javascript"); |
| 1892 | 1946 |
| 1893 RegisterMonitorRequestHandler(); | 1947 RegisterMonitorRequestHandler(); |
| 1894 StartServerAndNavigateToSetup(); | 1948 StartServerAndNavigateToSetup(); |
| 1895 SetupForNavigationPreloadTest(page_url, worker_url); | 1949 SetupForNavigationPreloadTest(page_url, worker_url); |
| 1896 | 1950 |
| 1897 EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); | 1951 EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete()); |
| 1898 | 1952 |
| 1953 scoped_refptr<ConsoleMessageContextObserver> console_observer = |
| 1954 new ConsoleMessageContextObserver(wrapper()); |
| 1955 console_observer->Init(); |
| 1956 |
| 1899 const base::string16 title = base::ASCIIToUTF16("REJECTED"); | 1957 const base::string16 title = base::ASCIIToUTF16("REJECTED"); |
| 1900 TitleWatcher title_watcher(shell()->web_contents(), title); | 1958 TitleWatcher title_watcher(shell()->web_contents(), title); |
| 1901 title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("RESOLVED")); | 1959 title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("RESOLVED")); |
| 1902 NavigateToURL(shell(), page_url); | 1960 NavigateToURL(shell(), page_url); |
| 1903 EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); | 1961 EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); |
| 1904 EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 1962 EXPECT_EQ("NetworkError: " + kNavigationPreloadNetworkError, |
| 1905 GetTextContent()); | 1963 GetTextContent()); |
| 1964 |
| 1965 console_observer->WaitForConsoleMessages(1); |
| 1966 const base::string16 expected = |
| 1967 base::ASCIIToUTF16("net::ERR_CONNECTION_REFUSED"); |
| 1968 std::vector<base::string16> messages = console_observer->messages(); |
| 1969 EXPECT_NE(base::string16::npos, messages[0].find(expected)); |
| 1906 } | 1970 } |
| 1907 | 1971 |
| 1908 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, | 1972 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, |
| 1909 CanceledByInterceptor) { | 1973 CanceledByInterceptor) { |
| 1910 content::ResourceDispatcherHost::Get()->RegisterInterceptor( | 1974 content::ResourceDispatcherHost::Get()->RegisterInterceptor( |
| 1911 kNavigationPreloadHeaderName, "", | 1975 kNavigationPreloadHeaderName, "", |
| 1912 base::Bind(&CancellingInterceptorCallback)); | 1976 base::Bind(&CancellingInterceptorCallback)); |
| 1913 | 1977 |
| 1914 const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 1978 const char kPageUrl[] = "/service_worker/navigation_preload.html"; |
| 1915 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 1979 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; |
| 1916 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 1980 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); |
| 1917 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 1981 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); |
| 1918 RegisterStaticFile( | 1982 RegisterStaticFile( |
| 1919 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, | 1983 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, |
| 1920 "text/javascript"); | 1984 "text/javascript"); |
| 1921 | 1985 |
| 1922 EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 1986 EXPECT_EQ("NetworkError: " + kNavigationPreloadAbortError, |
| 1923 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); | 1987 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); |
| 1924 } | 1988 } |
| 1925 | 1989 |
| 1926 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, | 1990 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, |
| 1927 PreloadHeadersSimple) { | 1991 PreloadHeadersSimple) { |
| 1928 const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 1992 const char kPageUrl[] = "/service_worker/navigation_preload.html"; |
| 1929 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 1993 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; |
| 1930 const char kPage[] = "<title>ERROR</title>Hello world."; | 1994 const char kPage[] = "<title>ERROR</title>Hello world."; |
| 1931 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 1995 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); |
| 1932 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 1996 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2029 "\r\n"; | 2093 "\r\n"; |
| 2030 const char kRedirectedPage[] = "<title>ERROR</title>Redirected page."; | 2094 const char kRedirectedPage[] = "<title>ERROR</title>Redirected page."; |
| 2031 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 2095 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); |
| 2032 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 2096 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); |
| 2033 RegisterCustomResponse(kPageUrl, kPageResponse); | 2097 RegisterCustomResponse(kPageUrl, kPageResponse); |
| 2034 RegisterStaticFile( | 2098 RegisterStaticFile( |
| 2035 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, | 2099 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, |
| 2036 "text/javascript"); | 2100 "text/javascript"); |
| 2037 RegisterStaticFile(kRedirectedPageUrl1, kRedirectedPage, "text/html"); | 2101 RegisterStaticFile(kRedirectedPageUrl1, kRedirectedPage, "text/html"); |
| 2038 | 2102 |
| 2103 scoped_refptr<ConsoleMessageContextObserver> console_observer = |
| 2104 new ConsoleMessageContextObserver(wrapper()); |
| 2105 console_observer->Init(); |
| 2106 |
| 2039 // According to the spec, multiple Location headers is not an error. So the | 2107 // According to the spec, multiple Location headers is not an error. So the |
| 2040 // preloadResponse must be resolved with an opaque redirect response. | 2108 // preloadResponse must be resolved with an opaque redirect response. |
| 2041 // But Chrome treats multiple Location headers as an error (crbug.com/98895). | 2109 // But Chrome treats multiple Location headers as an error (crbug.com/98895). |
| 2042 EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 2110 EXPECT_EQ("NetworkError: " + kNavigationPreloadNetworkError, |
| 2043 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); | 2111 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); |
| 2044 | 2112 |
| 2113 console_observer->WaitForConsoleMessages(1); |
| 2114 const base::string16 expected = |
| 2115 base::ASCIIToUTF16("ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION"); |
| 2116 std::vector<base::string16> messages = console_observer->messages(); |
| 2117 EXPECT_NE(base::string16::npos, messages[0].find(expected)); |
| 2118 |
| 2045 // The page request must be sent only once, since the worker responded with | 2119 // The page request must be sent only once, since the worker responded with |
| 2046 // a generated Response. | 2120 // a generated Response. |
| 2047 EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 2121 EXPECT_EQ(1, GetRequestCount(kPageUrl)); |
| 2048 // The redirected request must not be sent. | 2122 // The redirected request must not be sent. |
| 2049 EXPECT_EQ(0, GetRequestCount(kRedirectedPageUrl1)); | 2123 EXPECT_EQ(0, GetRequestCount(kRedirectedPageUrl1)); |
| 2050 EXPECT_EQ(0, GetRequestCount(kRedirectedPageUrl2)); | 2124 EXPECT_EQ(0, GetRequestCount(kRedirectedPageUrl2)); |
| 2051 } | 2125 } |
| 2052 | 2126 |
| 2053 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, | 2127 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, |
| 2054 InvalidRedirect_InvalidLocation) { | 2128 InvalidRedirect_InvalidLocation) { |
| 2055 const char kPageUrl[] = "/service_worker/navigation_preload.html"; | 2129 const char kPageUrl[] = "/service_worker/navigation_preload.html"; |
| 2056 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; | 2130 const char kWorkerUrl[] = "/service_worker/navigation_preload.js"; |
| 2057 const char kPageResponse[] = | 2131 const char kPageResponse[] = |
| 2058 "HTTP/1.1 302 Found\r\n" | 2132 "HTTP/1.1 302 Found\r\n" |
| 2059 "Connection: close\r\n" | 2133 "Connection: close\r\n" |
| 2060 "Location: http://\r\n" | 2134 "Location: http://\r\n" |
| 2061 "\r\n"; | 2135 "\r\n"; |
| 2062 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); | 2136 const GURL page_url = embedded_test_server()->GetURL(kPageUrl); |
| 2063 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); | 2137 const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl); |
| 2064 RegisterCustomResponse(kPageUrl, kPageResponse); | 2138 RegisterCustomResponse(kPageUrl, kPageResponse); |
| 2065 RegisterStaticFile( | 2139 RegisterStaticFile( |
| 2066 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, | 2140 kWorkerUrl, kEnableNavigationPreloadScript + kPreloadResponseTestScript, |
| 2067 "text/javascript"); | 2141 "text/javascript"); |
| 2068 | 2142 |
| 2069 // TODO(horo): According to the spec, even if the location URL is invalid, the | 2143 // TODO(horo): According to the spec, even if the location URL is invalid, the |
| 2070 // preloadResponse must be resolve with an opaque redirect response. But | 2144 // preloadResponse must be resolve with an opaque redirect response. But |
| 2071 // currently Chrome handles the invalid location URL in the browser process as | 2145 // currently Chrome handles the invalid location URL in the browser process as |
| 2072 // an error. crbug.com/707185 | 2146 // an error. crbug.com/707185 |
| 2073 EXPECT_EQ("NetworkError: Service Worker navigation preload network error.", | 2147 EXPECT_EQ("NetworkError: " + kNavigationPreloadAbortError, |
| 2074 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); | 2148 LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED")); |
| 2075 | 2149 |
| 2076 // The page request must be sent only once, since the worker responded with | 2150 // The page request must be sent only once, since the worker responded with |
| 2077 // a generated Response. | 2151 // a generated Response. |
| 2078 EXPECT_EQ(1, GetRequestCount(kPageUrl)); | 2152 EXPECT_EQ(1, GetRequestCount(kPageUrl)); |
| 2079 } | 2153 } |
| 2080 | 2154 |
| 2081 // Tests responding with the navigation preload response when the navigation | 2155 // Tests responding with the navigation preload response when the navigation |
| 2082 // occurred after a redirect. | 2156 // occurred after a redirect. |
| 2083 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, | 2157 IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, |
| (...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2934 // effect in CanSuspendRenderer(). | 3008 // effect in CanSuspendRenderer(). |
| 2935 shell()->web_contents()->WasHidden(); | 3009 shell()->web_contents()->WasHidden(); |
| 2936 EXPECT_TRUE(rph->IsProcessBackgrounded()); | 3010 EXPECT_TRUE(rph->IsProcessBackgrounded()); |
| 2937 | 3011 |
| 2938 // The process which has service worker thread shouldn't be suspended. | 3012 // The process which has service worker thread shouldn't be suspended. |
| 2939 EXPECT_FALSE(memory_coordinator->CanSuspendRenderer(render_process_id)); | 3013 EXPECT_FALSE(memory_coordinator->CanSuspendRenderer(render_process_id)); |
| 2940 } | 3014 } |
| 2941 #endif | 3015 #endif |
| 2942 | 3016 |
| 2943 } // namespace content | 3017 } // namespace content |
| OLD | NEW |