Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3193)

Unified Diff: chrome/browser/errorpage_browsertest.cc

Issue 138513002: Plumb network stack information about existence of cached copy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/errorpage_browsertest.cc
diff --git a/chrome/browser/errorpage_browsertest.cc b/chrome/browser/errorpage_browsertest.cc
index e2afcbf59b7c601ef1b81187426d68a6d2e86b55..7a7b66748ec9edf29a9965c148be8accb81a7b15 100644
--- a/chrome/browser/errorpage_browsertest.cc
+++ b/chrome/browser/errorpage_browsertest.cc
@@ -6,6 +6,8 @@
#include "base/prefs/pref_service.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.h"
@@ -25,6 +27,12 @@
#include "content/test/net/url_request_mock_http_job.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_transaction.h"
+#include "net/http/http_transaction_factory.h"
+#include "net/test/spawned_test_server/spawned_test_server.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_job_factory.h"
@@ -121,7 +129,6 @@ class ErrorPageTest : public InProcessBrowserTest {
}
};
-
class TestFailProvisionalLoadObserver : public content::WebContentsObserver {
public:
explicit TestFailProvisionalLoadObserver(content::WebContents* contents)
@@ -148,6 +155,143 @@ class TestFailProvisionalLoadObserver : public content::WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver);
};
+class TestNetworkTransaction : public net::HttpTransaction {
+ public:
+ explicit TestNetworkTransaction(enum net::Error err): err_(err) {
+ DCHECK_NE(net::OK, err);
+ }
+ virtual ~TestNetworkTransaction() {}
+
+ // net::HttpTransaction
+ virtual int Start(const net::HttpRequestInfo* request_info,
+ const net::CompletionCallback& callback,
+ const net::BoundNetLog& net_log) OVERRIDE {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(callback, err_));
+ return net::ERR_IO_PENDING;
+ }
+ virtual int RestartIgnoringLastError(
+ const net::CompletionCallback& callback) OVERRIDE {
+ return net::ERR_FAILED;
+ }
+ virtual int RestartWithCertificate(
+ net::X509Certificate* client_cert,
+ const net::CompletionCallback& callback) OVERRIDE {
+ return net::ERR_FAILED;
+ }
+ virtual int RestartWithAuth(
+ const net::AuthCredentials& credentials,
+ const net::CompletionCallback& callback) OVERRIDE {
+ return net::ERR_FAILED;
+ }
+ virtual bool IsReadyToRestartForAuth() OVERRIDE {
+ return false;
+ }
+ virtual int Read(net::IOBuffer* buf, int buf_len,
+ const net::CompletionCallback& callback) OVERRIDE {
+ NOTREACHED();
+ return net::ERR_FAILED;
+ }
+ virtual void StopCaching() OVERRIDE {}
+ virtual bool GetFullRequestHeaders(
+ net::HttpRequestHeaders* headers) const OVERRIDE {
+ return false;
+ }
+ virtual int64 GetTotalReceivedBytes() const OVERRIDE {
+ return 0;
+ }
+ virtual void DoneReading() OVERRIDE {
+ NOTREACHED();
+ }
+ virtual const net::HttpResponseInfo* GetResponseInfo() const OVERRIDE {
+ return NULL;
+ }
+ virtual net::LoadState GetLoadState() const OVERRIDE {
+ return net::LOAD_STATE_IDLE;
+ }
+ virtual net::UploadProgress GetUploadProgress() const OVERRIDE {
+ return net::UploadProgress();
+ }
+ virtual bool GetLoadTimingInfo(
+ net::LoadTimingInfo* load_timing_info) const OVERRIDE {
+ // Shouldn't be relevant; using the minimal set from
+ // http_transaction_unittest.cc MockNetworkTransaction::GetLoadTimingInfo().
+ load_timing_info->socket_reused = true;
+ load_timing_info->send_start = base::TimeTicks::Now();
+ load_timing_info->send_end = base::TimeTicks::Now();
+ return true;
+ }
+ virtual void SetPriority(net::RequestPriority priority) OVERRIDE {}
+ virtual void SetWebSocketHandshakeStreamCreateHelper(
+ net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE {
+ NOTREACHED();
+ }
+ virtual void SetBeforeNetworkStartCallback(
+ const BeforeNetworkStartCallback& callback) OVERRIDE {
+ }
+ virtual int ResumeNetworkStart() OVERRIDE {
+ NOTREACHED();
+ return net::ERR_FAILED;
+ }
+
+ private:
+ enum net::Error err_;
+};
+
+// Creates transactions that always (asynchronously) return |err|.
+// |err| must not be net::OK.
+class TestNetworkTransactionFactory : public net::HttpTransactionFactory {
+ public:
+ explicit TestNetworkTransactionFactory(enum net::Error err) : err_(err) {}
+ virtual ~TestNetworkTransactionFactory() {}
+
+ // net::HttpTransactionFactory:
+ virtual int CreateTransaction(
+ net::RequestPriority priority,
+ scoped_ptr<net::HttpTransaction>* trans) OVERRIDE {
+ trans->reset(new TestNetworkTransaction(err_));
+ return net::OK;
+ }
+ virtual net::HttpCache* GetCache() OVERRIDE {
+ return NULL;
+ }
+ virtual net::HttpNetworkSession* GetSession() OVERRIDE {
+ return NULL; // TODO(rdsmith): Is this really safe?
+ }
+
+ static void SetupInstance(net::URLRequestContextGetter* getter,
+ enum net::Error err) {
+ DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::HttpCache* cache(
+ getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
+ DCHECK(cache);
+ DCHECK(!old_network_layer_.get());
+ scoped_ptr<TestNetworkTransactionFactory> factory(
+ new TestNetworkTransactionFactory(err));
+ old_network_layer_ = cache->SetNetworkLayerForTesting(
+ factory.PassAs<net::HttpTransactionFactory>());
+ }
+
+ static void TearDownInstance(net::URLRequestContextGetter* getter) {
+ DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO));
+ net::HttpCache* cache(
+ getter->GetURLRequestContext()->http_transaction_factory()->GetCache());
+ DCHECK(cache);
+ DCHECK(old_network_layer_.get());
+ cache->SetNetworkLayerForTesting(old_network_layer_.Pass());
+ }
+
+ private:
+ enum net::Error err_;
+
+ // It is the caller's responsibility to make sure that TearDownInstance()
+ // is called so that this does not leak.
+ static scoped_ptr<net::HttpTransactionFactory> old_network_layer_;
+};
+
+scoped_ptr<net::HttpTransactionFactory>
+TestNetworkTransactionFactory::old_network_layer_;
+
// See crbug.com/109669
#if defined(USE_AURA) || defined(OS_WIN)
#define MAYBE_DNSError_Basic DISABLED_DNSError_Basic
@@ -356,6 +500,76 @@ IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) {
1);
}
+// Checks that when an error occurs, the stale cache status of the page
+// is correctly transferred.
+IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) {
+ ASSERT_TRUE(test_server()->Start());
+ // Load cache with entry with "nocache" set, to create stale
+ // cache.
+ GURL test_url(test_server()->GetURL("files/nocache.html"));
+ NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1);
+
+ // Reload same URL after forcing an error from the the network layer;
+ // confirm that the error page is told the cached copy exists.
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+ browser()->profile()->GetRequestContext();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&TestNetworkTransactionFactory::SetupInstance,
+ url_request_context_getter,
+ // Note that we can't use an error that'll invoke the link
+ // doctor. In normal network error conditions that would
+ // work (because the link doctor fetch would also fail,
+ // putting us back in the main offline path), but
+ // SetUrlRequestMocksEnabled() has also specfied a link
+ // doctor mock, which will be accessible because it
+ // won't go through the network cache.
+ net::ERR_FAILED));
+
+ ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+ // First fails, second to error page.
+ // TODO(rdsmith): The above is wrong; why?
+ browser(), test_url, 1 /* 2 */);
+
+ content::WebContents* wc =
+ browser()->tab_strip_model()->GetActiveWebContents();
+ const char* js_cache_probe =
+ "(function () {\n"
+ "if ('staleCopyInCache' in templateData) {\n"
+ "return templateData.staleCopyInCache;\n"
+ "} else {\n"
+ "return 'Undefined';\n"
+ "}\n"
+ "})();";
+
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(
+ wc->GetRenderViewHost(), js_cache_probe);
+ ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)) << "Type is "
+ << value->GetType();
+ bool result = false;
+ EXPECT_TRUE(value->GetAsBoolean(&result));
+ EXPECT_TRUE(result);
+
+ // Clear the cache and reload the same URL; confirm the error page is told
+ // that there is no cached copy.
+ BrowsingDataRemover* remover =
+ BrowsingDataRemover::CreateForUnboundedRange(browser()->profile());
+ remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
+ BrowsingDataHelper::UNPROTECTED_WEB);
+ ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
+ browser(), test_url, 1); // First fails, second to error page.
+ value = content::ExecuteScriptAndGetValue(
+ wc->GetRenderViewHost(), js_cache_probe);
+ ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN));
+ EXPECT_TRUE(value->GetAsBoolean(&result));
+ EXPECT_FALSE(result);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&TestNetworkTransactionFactory::TearDownInstance,
+ url_request_context_getter));
+}
+
// Returns Javascript code that executes plain text search for the page.
// Pass into content::ExecuteScriptAndExtractBool as |script| parameter.
std::string GetTextContentContainsStringScript(

Powered by Google App Engine
This is Rietveld 408576698