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