OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/prefs/pref_service.h" | 6 #include "base/prefs/pref_service.h" |
7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 10 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
9 #include "chrome/browser/google/google_util.h" | 11 #include "chrome/browser/google/google_util.h" |
10 #include "chrome/browser/net/url_request_mock_util.h" | 12 #include "chrome/browser/net/url_request_mock_util.h" |
11 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/browser_commands.h" | 15 #include "chrome/browser/ui/browser_commands.h" |
14 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
15 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
16 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
17 #include "chrome/test/base/ui_test_utils.h" | 19 #include "chrome/test/base/ui_test_utils.h" |
18 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
19 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
20 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
21 #include "content/public/browser/web_contents_observer.h" | 23 #include "content/public/browser/web_contents_observer.h" |
22 #include "content/public/test/browser_test_utils.h" | 24 #include "content/public/test/browser_test_utils.h" |
23 #include "content/public/test/test_navigation_observer.h" | 25 #include "content/public/test/test_navigation_observer.h" |
24 #include "content/test/net/url_request_failed_job.h" | 26 #include "content/test/net/url_request_failed_job.h" |
25 #include "content/test/net/url_request_mock_http_job.h" | 27 #include "content/test/net/url_request_mock_http_job.h" |
26 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
27 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
| 30 #include "net/http/http_cache.h" |
| 31 #include "net/http/http_transaction.h" |
| 32 #include "net/http/http_transaction_factory.h" |
| 33 #include "net/test/spawned_test_server/spawned_test_server.h" |
| 34 #include "net/url_request/url_request_context.h" |
| 35 #include "net/url_request/url_request_context_getter.h" |
28 #include "net/url_request/url_request_filter.h" | 36 #include "net/url_request/url_request_filter.h" |
29 #include "net/url_request/url_request_job_factory.h" | 37 #include "net/url_request/url_request_job_factory.h" |
30 | 38 |
31 using content::BrowserThread; | 39 using content::BrowserThread; |
32 using content::NavigationController; | 40 using content::NavigationController; |
33 using content::URLRequestFailedJob; | 41 using content::URLRequestFailedJob; |
34 | 42 |
35 namespace { | 43 namespace { |
36 | 44 |
37 class ErrorPageTest : public InProcessBrowserTest { | 45 class ErrorPageTest : public InProcessBrowserTest { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } else { | 122 } else { |
115 FAIL(); | 123 FAIL(); |
116 } | 124 } |
117 test_navigation_observer.Wait(); | 125 test_navigation_observer.Wait(); |
118 | 126 |
119 EXPECT_EQ(title_watcher.WaitAndGetTitle(), | 127 EXPECT_EQ(title_watcher.WaitAndGetTitle(), |
120 base::ASCIIToUTF16(expected_title)); | 128 base::ASCIIToUTF16(expected_title)); |
121 } | 129 } |
122 }; | 130 }; |
123 | 131 |
124 | |
125 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { | 132 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { |
126 public: | 133 public: |
127 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) | 134 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) |
128 : content::WebContentsObserver(contents) {} | 135 : content::WebContentsObserver(contents) {} |
129 virtual ~TestFailProvisionalLoadObserver() {} | 136 virtual ~TestFailProvisionalLoadObserver() {} |
130 | 137 |
131 // This method is invoked when the provisional load failed. | 138 // This method is invoked when the provisional load failed. |
132 virtual void DidFailProvisionalLoad( | 139 virtual void DidFailProvisionalLoad( |
133 int64 frame_id, | 140 int64 frame_id, |
134 const base::string16& frame_unique_name, | 141 const base::string16& frame_unique_name, |
135 bool is_main_frame, | 142 bool is_main_frame, |
136 const GURL& validated_url, | 143 const GURL& validated_url, |
137 int error_code, | 144 int error_code, |
138 const base::string16& error_description, | 145 const base::string16& error_description, |
139 content::RenderViewHost* render_view_host) OVERRIDE { | 146 content::RenderViewHost* render_view_host) OVERRIDE { |
140 fail_url_ = validated_url; | 147 fail_url_ = validated_url; |
141 } | 148 } |
142 | 149 |
143 const GURL& fail_url() const { return fail_url_; } | 150 const GURL& fail_url() const { return fail_url_; } |
144 | 151 |
145 private: | 152 private: |
146 GURL fail_url_; | 153 GURL fail_url_; |
147 | 154 |
148 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); | 155 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); |
149 }; | 156 }; |
150 | 157 |
| 158 class TestNetworkTransaction : public net::HttpTransaction { |
| 159 public: |
| 160 explicit TestNetworkTransaction(enum net::Error err): err_(err) { |
| 161 DCHECK_NE(net::OK, err); |
| 162 } |
| 163 virtual ~TestNetworkTransaction() {} |
| 164 |
| 165 // net::HttpTransaction |
| 166 virtual int Start(const net::HttpRequestInfo* request_info, |
| 167 const net::CompletionCallback& callback, |
| 168 const net::BoundNetLog& net_log) OVERRIDE { |
| 169 base::MessageLoop::current()->PostTask( |
| 170 FROM_HERE, base::Bind(callback, err_)); |
| 171 return net::ERR_IO_PENDING; |
| 172 } |
| 173 virtual int RestartIgnoringLastError( |
| 174 const net::CompletionCallback& callback) OVERRIDE { |
| 175 return net::ERR_FAILED; |
| 176 } |
| 177 virtual int RestartWithCertificate( |
| 178 net::X509Certificate* client_cert, |
| 179 const net::CompletionCallback& callback) OVERRIDE { |
| 180 return net::ERR_FAILED; |
| 181 } |
| 182 virtual int RestartWithAuth( |
| 183 const net::AuthCredentials& credentials, |
| 184 const net::CompletionCallback& callback) OVERRIDE { |
| 185 return net::ERR_FAILED; |
| 186 } |
| 187 virtual bool IsReadyToRestartForAuth() OVERRIDE { |
| 188 return false; |
| 189 } |
| 190 virtual int Read(net::IOBuffer* buf, int buf_len, |
| 191 const net::CompletionCallback& callback) OVERRIDE { |
| 192 NOTREACHED(); |
| 193 return net::ERR_FAILED; |
| 194 } |
| 195 virtual void StopCaching() OVERRIDE {} |
| 196 virtual bool GetFullRequestHeaders( |
| 197 net::HttpRequestHeaders* headers) const OVERRIDE { |
| 198 return false; |
| 199 } |
| 200 virtual int64 GetTotalReceivedBytes() const OVERRIDE { |
| 201 return 0; |
| 202 } |
| 203 virtual void DoneReading() OVERRIDE { |
| 204 NOTREACHED(); |
| 205 } |
| 206 virtual const net::HttpResponseInfo* GetResponseInfo() const OVERRIDE { |
| 207 return NULL; |
| 208 } |
| 209 virtual net::LoadState GetLoadState() const OVERRIDE { |
| 210 return net::LOAD_STATE_IDLE; |
| 211 } |
| 212 virtual net::UploadProgress GetUploadProgress() const OVERRIDE { |
| 213 return net::UploadProgress(); |
| 214 } |
| 215 virtual bool GetLoadTimingInfo( |
| 216 net::LoadTimingInfo* load_timing_info) const OVERRIDE { |
| 217 // Shouldn't be relevant; using the minimal set from |
| 218 // http_transaction_unittest.cc MockNetworkTransaction::GetLoadTimingInfo(). |
| 219 load_timing_info->socket_reused = true; |
| 220 load_timing_info->send_start = base::TimeTicks::Now(); |
| 221 load_timing_info->send_end = base::TimeTicks::Now(); |
| 222 return true; |
| 223 } |
| 224 virtual void SetPriority(net::RequestPriority priority) OVERRIDE {} |
| 225 virtual void SetWebSocketHandshakeStreamCreateHelper( |
| 226 net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE { |
| 227 NOTREACHED(); |
| 228 } |
| 229 virtual void SetBeforeNetworkStartCallback( |
| 230 const BeforeNetworkStartCallback& callback) OVERRIDE { |
| 231 } |
| 232 virtual int ResumeNetworkStart() OVERRIDE { |
| 233 NOTREACHED(); |
| 234 return net::ERR_FAILED; |
| 235 } |
| 236 |
| 237 private: |
| 238 enum net::Error err_; |
| 239 }; |
| 240 |
| 241 // Creates transactions that always (asynchronously) return |err|. |
| 242 // |err| must not be net::OK. |
| 243 class TestNetworkTransactionFactory : public net::HttpTransactionFactory { |
| 244 public: |
| 245 explicit TestNetworkTransactionFactory(enum net::Error err) : err_(err) {} |
| 246 virtual ~TestNetworkTransactionFactory() {} |
| 247 |
| 248 // net::HttpTransactionFactory: |
| 249 virtual int CreateTransaction( |
| 250 net::RequestPriority priority, |
| 251 scoped_ptr<net::HttpTransaction>* trans) OVERRIDE { |
| 252 trans->reset(new TestNetworkTransaction(err_)); |
| 253 return net::OK; |
| 254 } |
| 255 virtual net::HttpCache* GetCache() OVERRIDE { |
| 256 return NULL; |
| 257 } |
| 258 virtual net::HttpNetworkSession* GetSession() OVERRIDE { |
| 259 return NULL; // TODO(rdsmith): Is this really safe? |
| 260 } |
| 261 |
| 262 static void SetupInstance(net::URLRequestContextGetter* getter, |
| 263 enum net::Error err) { |
| 264 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 265 net::HttpCache* cache( |
| 266 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| 267 DCHECK(cache); |
| 268 DCHECK(!old_network_layer_.get()); |
| 269 scoped_ptr<TestNetworkTransactionFactory> factory( |
| 270 new TestNetworkTransactionFactory(err)); |
| 271 old_network_layer_ = cache->SetNetworkLayerForTesting( |
| 272 factory.PassAs<net::HttpTransactionFactory>()); |
| 273 } |
| 274 |
| 275 static void TearDownInstance(net::URLRequestContextGetter* getter) { |
| 276 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 277 net::HttpCache* cache( |
| 278 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| 279 DCHECK(cache); |
| 280 DCHECK(old_network_layer_.get()); |
| 281 cache->SetNetworkLayerForTesting(old_network_layer_.Pass()); |
| 282 } |
| 283 |
| 284 private: |
| 285 enum net::Error err_; |
| 286 |
| 287 // It is the caller's responsibility to make sure that TearDownInstance() |
| 288 // is called so that this does not leak. |
| 289 static scoped_ptr<net::HttpTransactionFactory> old_network_layer_; |
| 290 }; |
| 291 |
| 292 scoped_ptr<net::HttpTransactionFactory> |
| 293 TestNetworkTransactionFactory::old_network_layer_; |
| 294 |
151 // See crbug.com/109669 | 295 // See crbug.com/109669 |
152 #if defined(USE_AURA) || defined(OS_WIN) | 296 #if defined(USE_AURA) || defined(OS_WIN) |
153 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic | 297 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic |
154 #else | 298 #else |
155 #define MAYBE_DNSError_Basic DNSError_Basic | 299 #define MAYBE_DNSError_Basic DNSError_Basic |
156 #endif | 300 #endif |
157 // Test that a DNS error occuring in the main frame redirects to an error page. | 301 // Test that a DNS error occuring in the main frame redirects to an error page. |
158 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) { | 302 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) { |
159 // The first navigation should fail, and the second one should be the error | 303 // The first navigation should fail, and the second one should be the error |
160 // page. | 304 // page. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 | 493 |
350 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. | 494 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. |
351 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { | 495 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { |
352 NavigateToURLAndWaitForTitle( | 496 NavigateToURLAndWaitForTitle( |
353 content::URLRequestMockHTTPJob::GetMockUrl( | 497 content::URLRequestMockHTTPJob::GetMockUrl( |
354 base::FilePath(FILE_PATH_LITERAL("page404.html"))), | 498 base::FilePath(FILE_PATH_LITERAL("page404.html"))), |
355 "SUCCESS", | 499 "SUCCESS", |
356 1); | 500 1); |
357 } | 501 } |
358 | 502 |
| 503 // Checks that when an error occurs, the stale cache status of the page |
| 504 // is correctly transferred. |
| 505 IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) { |
| 506 ASSERT_TRUE(test_server()->Start()); |
| 507 // Load cache with entry with "nocache" set, to create stale |
| 508 // cache. |
| 509 GURL test_url(test_server()->GetURL("files/nocache.html")); |
| 510 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); |
| 511 |
| 512 // Reload same URL after forcing an error from the the network layer; |
| 513 // confirm that the error page is told the cached copy exists. |
| 514 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 515 browser()->profile()->GetRequestContext(); |
| 516 BrowserThread::PostTask( |
| 517 BrowserThread::IO, FROM_HERE, |
| 518 base::Bind(&TestNetworkTransactionFactory::SetupInstance, |
| 519 url_request_context_getter, |
| 520 // Note that we can't use an error that'll invoke the link |
| 521 // doctor. In normal network error conditions that would |
| 522 // work (because the link doctor fetch would also fail, |
| 523 // putting us back in the main offline path), but |
| 524 // SetUrlRequestMocksEnabled() has also specfied a link |
| 525 // doctor mock, which will be accessible because it |
| 526 // won't go through the network cache. |
| 527 net::ERR_FAILED)); |
| 528 |
| 529 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 530 // First fails, second to error page. |
| 531 // TODO(rdsmith): The above is wrong; why? |
| 532 browser(), test_url, 1 /* 2 */); |
| 533 |
| 534 content::WebContents* wc = |
| 535 browser()->tab_strip_model()->GetActiveWebContents(); |
| 536 const char* js_cache_probe = |
| 537 "(function () {\n" |
| 538 "if ('staleCopyInCache' in templateData) {\n" |
| 539 "return templateData.staleCopyInCache;\n" |
| 540 "} else {\n" |
| 541 "return 'Undefined';\n" |
| 542 "}\n" |
| 543 "})();"; |
| 544 |
| 545 scoped_ptr<base::Value> value = |
| 546 content::ExecuteScriptAndGetValue( |
| 547 wc->GetRenderViewHost(), js_cache_probe); |
| 548 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)) << "Type is " |
| 549 << value->GetType(); |
| 550 bool result = false; |
| 551 EXPECT_TRUE(value->GetAsBoolean(&result)); |
| 552 EXPECT_TRUE(result); |
| 553 |
| 554 // Clear the cache and reload the same URL; confirm the error page is told |
| 555 // that there is no cached copy. |
| 556 BrowsingDataRemover* remover = |
| 557 BrowsingDataRemover::CreateForUnboundedRange(browser()->profile()); |
| 558 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, |
| 559 BrowsingDataHelper::UNPROTECTED_WEB); |
| 560 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 561 browser(), test_url, 1); // First fails, second to error page. |
| 562 value = content::ExecuteScriptAndGetValue( |
| 563 wc->GetRenderViewHost(), js_cache_probe); |
| 564 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)); |
| 565 EXPECT_TRUE(value->GetAsBoolean(&result)); |
| 566 EXPECT_FALSE(result); |
| 567 BrowserThread::PostTask( |
| 568 BrowserThread::IO, FROM_HERE, |
| 569 base::Bind(&TestNetworkTransactionFactory::TearDownInstance, |
| 570 url_request_context_getter)); |
| 571 } |
| 572 |
359 // Returns Javascript code that executes plain text search for the page. | 573 // Returns Javascript code that executes plain text search for the page. |
360 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. | 574 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. |
361 std::string GetTextContentContainsStringScript( | 575 std::string GetTextContentContainsStringScript( |
362 const std::string& value_to_search) { | 576 const std::string& value_to_search) { |
363 return base::StringPrintf( | 577 return base::StringPrintf( |
364 "var textContent = document.body.textContent;" | 578 "var textContent = document.body.textContent;" |
365 "var hasError = textContent.indexOf('%s') >= 0;" | 579 "var hasError = textContent.indexOf('%s') >= 0;" |
366 "domAutomationController.send(hasError);", | 580 "domAutomationController.send(hasError);", |
367 value_to_search.c_str()); | 581 value_to_search.c_str()); |
368 } | 582 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 | 713 |
500 bool result = false; | 714 bool result = false; |
501 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 715 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
502 browser()->tab_strip_model()->GetActiveWebContents(), | 716 browser()->tab_strip_model()->GetActiveWebContents(), |
503 GetTextContentContainsStringScript(kHostnameJSUnicode), | 717 GetTextContentContainsStringScript(kHostnameJSUnicode), |
504 &result)); | 718 &result)); |
505 EXPECT_TRUE(result); | 719 EXPECT_TRUE(result); |
506 } | 720 } |
507 | 721 |
508 } // namespace | 722 } // namespace |
OLD | NEW |