diff options
author | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-06 23:08:37 +0000 |
---|---|---|
committer | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-06 23:08:37 +0000 |
commit | dcbe3df77892fded9f0afa3fe01112f242b6fff7 (patch) | |
tree | cc4a01616ff566c53df7b4d1c1b821850abcfcdf /content | |
parent | 097782be0628a771d04d49dbb06360b6232cb340 (diff) | |
download | chromium_src-dcbe3df77892fded9f0afa3fe01112f242b6fff7.zip chromium_src-dcbe3df77892fded9f0afa3fe01112f242b6fff7.tar.gz chromium_src-dcbe3df77892fded9f0afa3fe01112f242b6fff7.tar.bz2 |
Plumb network stack information about existence of cached copy
through to error page. Specifically, add a "stale_copy_in_cache" argument to all of (ordered from Browser->Renderer):
* ResourceMsg_RequestComplete IPC message.
* ResourceDispatcher::OnRequestComplete
* ResourceLoaderBridge::Peer::OnCompletedRequest.
* All subclasses of RLB::P::OnCompleted Request, including WebURLLoaderImpl::context::OnCompletedRequest.
* Blink WebURLError and ResourceError classes (https://codereview.chromium.org/138493002).
* LocalizedError::GetStrings.
This is a paired commit with the blink CL
https://codereview.chromium.org/138493002. That CL must be landed before this one.
BUG=329620
Review URL: https://codereview.chromium.org/138513002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249527 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/loader/async_resource_handler.cc | 14 | ||||
-rw-r--r-- | content/browser/loader/resource_dispatcher_host_impl.cc | 13 | ||||
-rw-r--r-- | content/child/npapi/plugin_url_fetcher.cc | 1 | ||||
-rw-r--r-- | content/child/npapi/plugin_url_fetcher.h | 1 | ||||
-rw-r--r-- | content/child/resource_dispatcher.cc | 15 | ||||
-rw-r--r-- | content/child/resource_dispatcher.h | 7 | ||||
-rw-r--r-- | content/child/resource_dispatcher_unittest.cc | 3 | ||||
-rw-r--r-- | content/common/resource_messages.h | 25 | ||||
-rw-r--r-- | content/renderer/render_view_browsertest.cc | 225 | ||||
-rw-r--r-- | content/test/content_browser_test.cc | 23 | ||||
-rw-r--r-- | content/test/content_browser_test.h | 4 | ||||
-rw-r--r-- | content/test/data/nocache.html | 4 | ||||
-rw-r--r-- | content/test/data/nocache.html.mock-http-headers | 2 |
13 files changed, 302 insertions, 35 deletions
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc index 52c1d8f..2a35c4d 100644 --- a/content/browser/loader/async_resource_handler.cc +++ b/content/browser/loader/async_resource_handler.cc @@ -335,8 +335,6 @@ void AsyncResourceHandler::OnResponseCompleted( CHECK(status.status() != net::URLRequestStatus::SUCCESS || sent_received_response_msg_); - TimeTicks completion_time = TimeTicks::Now(); - int error_code = status.error(); bool was_ignored_by_handler = info->WasIgnoredByHandler(); @@ -356,12 +354,14 @@ void AsyncResourceHandler::OnResponseCompleted( error_code = net::ERR_FAILED; } + ResourceMsg_RequestCompleteData request_complete_data; + request_complete_data.error_code = error_code; + request_complete_data.was_ignored_by_handler = was_ignored_by_handler; + request_complete_data.exists_in_cache = request()->response_info().was_cached; + request_complete_data.security_info = security_info; + request_complete_data.completion_time = TimeTicks::Now(); info->filter()->Send( - new ResourceMsg_RequestComplete(request_id, - error_code, - was_ignored_by_handler, - security_info, - completion_time)); + new ResourceMsg_RequestComplete(request_id, request_complete_data)); } bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index b8bfaef..173202e 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc @@ -158,12 +158,15 @@ void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, filter->Send(sync_result); } else { // Tell the renderer that this request was disallowed. + ResourceMsg_RequestCompleteData request_complete_data; + request_complete_data.error_code = net::ERR_ABORTED; + request_complete_data.was_ignored_by_handler = false; + request_complete_data.exists_in_cache = false; + // No security info needed, connection not established. + request_complete_data.completion_time = base::TimeTicks(); + filter->Send(new ResourceMsg_RequestComplete( - request_id, - net::ERR_ABORTED, - false, - std::string(), // No security info needed, connection not established. - base::TimeTicks())); + request_id, request_complete_data)); } } diff --git a/content/child/npapi/plugin_url_fetcher.cc b/content/child/npapi/plugin_url_fetcher.cc index efc5b13..fa85dd6 100644 --- a/content/child/npapi/plugin_url_fetcher.cc +++ b/content/child/npapi/plugin_url_fetcher.cc @@ -341,6 +341,7 @@ void PluginURLFetcher::OnReceivedData(const char* data, void PluginURLFetcher::OnCompletedRequest( int error_code, bool was_ignored_by_handler, + bool stale_copy_in_cache, const std::string& security_info, const base::TimeTicks& completion_time) { if (multipart_delegate_) { diff --git a/content/child/npapi/plugin_url_fetcher.h b/content/child/npapi/plugin_url_fetcher.h index 2a0a10d..cf58813 100644 --- a/content/child/npapi/plugin_url_fetcher.h +++ b/content/child/npapi/plugin_url_fetcher.h @@ -62,6 +62,7 @@ class PluginURLFetcher : public webkit_glue::ResourceLoaderBridge::Peer { virtual void OnCompletedRequest( int error_code, bool was_ignored_by_handler, + bool stale_copy_in_cache, const std::string& security_info, const base::TimeTicks& completion_time) OVERRIDE; diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 6e4f438..d6affbb 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc @@ -521,10 +521,7 @@ void ResourceDispatcher::FollowPendingRedirect( void ResourceDispatcher::OnRequestComplete( int request_id, - int error_code, - bool was_ignored_by_handler, - const std::string& security_info, - const base::TimeTicks& browser_completion_time) { + const ResourceMsg_RequestCompleteData& request_complete_data) { TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete"); SiteIsolationPolicy::OnRequestComplete(request_id); @@ -540,17 +537,21 @@ void ResourceDispatcher::OnRequestComplete( if (delegate_) { ResourceLoaderBridge::Peer* new_peer = delegate_->OnRequestComplete( - request_info->peer, request_info->resource_type, error_code); + request_info->peer, request_info->resource_type, + request_complete_data.error_code); if (new_peer) request_info->peer = new_peer; } base::TimeTicks renderer_completion_time = ToRendererCompletionTime( - *request_info, browser_completion_time); + *request_info, request_complete_data.completion_time); // The request ID will be removed from our pending list in the destructor. // Normally, dispatching this message causes the reference-counted request to // die immediately. - peer->OnCompletedRequest(error_code, was_ignored_by_handler, security_info, + peer->OnCompletedRequest(request_complete_data.error_code, + request_complete_data.was_ignored_by_handler, + request_complete_data.exists_in_cache, + request_complete_data.security_info, renderer_completion_time); } diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index d85087d..4943765 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h @@ -20,6 +20,8 @@ #include "ipc/ipc_sender.h" #include "webkit/child/resource_loader_bridge.h" +struct ResourceMsg_RequestCompleteData; + namespace content { class ResourceDispatcherDelegate; struct ResourceResponseHead; @@ -150,10 +152,7 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { int encoded_data_length); void OnRequestComplete( int request_id, - int error_code, - bool was_ignored_by_handler, - const std::string& security_info, - const base::TimeTicks& completion_time); + const ResourceMsg_RequestCompleteData &request_complete_data); // Dispatch the message to one of the message response handlers. void DispatchMessage(const IPC::Message& message); diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc index 46869d5..7ff9ac3 100644 --- a/content/child/resource_dispatcher_unittest.cc +++ b/content/child/resource_dispatcher_unittest.cc @@ -70,6 +70,7 @@ class TestRequestCallback : public ResourceLoaderBridge::Peer { virtual void OnCompletedRequest( int error_code, bool was_ignored_by_handler, + bool stale_copy_in_cache, const std::string& security_info, const base::TimeTicks& completion_time) OVERRIDE { EXPECT_FALSE(complete_); @@ -295,6 +296,7 @@ class DeferredResourceLoadingTest : public ResourceDispatcherTest, virtual void OnCompletedRequest( int error_code, bool was_ignored_by_handler, + bool stale_copy_in_cache, const std::string& security_info, const base::TimeTicks& completion_time) OVERRIDE { } @@ -382,6 +384,7 @@ class TimeConversionTest : public ResourceDispatcherTest, virtual void OnCompletedRequest( int error_code, bool was_ignored_by_handler, + bool stale_copy_in_cache, const std::string& security_info, const base::TimeTicks& completion_time) OVERRIDE { } diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h index 8b346dd..100f75c 100644 --- a/content/common/resource_messages.h +++ b/content/common/resource_messages.h @@ -213,6 +213,24 @@ IPC_STRUCT_BEGIN(ResourceHostMsg_Request) IPC_STRUCT_MEMBER(bool, allow_download) IPC_STRUCT_END() +// Parameters for a ResourceMsg_RequestComplete +IPC_STRUCT_BEGIN(ResourceMsg_RequestCompleteData) + // The error code. + IPC_STRUCT_MEMBER(int, error_code) + + // Was ignored by the request handler. + IPC_STRUCT_MEMBER(bool, was_ignored_by_handler) + + // A copy of the data requested exists in the cache. + IPC_STRUCT_MEMBER(bool, exists_in_cache) + + // Serialized security info; see content/common/ssl_status_serialization.h. + IPC_STRUCT_MEMBER(std::string, security_info) + + // Time the request completed. + IPC_STRUCT_MEMBER(base::TimeTicks, completion_time) +IPC_STRUCT_END() + // Resource messages sent from the browser to the renderer. // Sent when the headers are available for a resource request. @@ -274,12 +292,9 @@ IPC_MESSAGE_CONTROL3(ResourceMsg_DataDownloaded, int /* encoded_data_length */) // Sent when the request has been completed. -IPC_MESSAGE_CONTROL5(ResourceMsg_RequestComplete, +IPC_MESSAGE_CONTROL2(ResourceMsg_RequestComplete, int /* request_id */, - int /* error_code */, - bool /* was_ignored_by_handler */, - std::string /* security info */, - base::TimeTicks /* completion_time */) + ResourceMsg_RequestCompleteData) // Resource messages sent from the renderer to the browser. diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 3a38ff2..a562d37 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc @@ -4,6 +4,8 @@ #include "base/basictypes.h" +#include "base/bind.h" +#include "base/callback.h" #include "base/memory/shared_memory.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -11,22 +13,40 @@ #include "content/common/frame_messages.h" #include "content/common/ssl_status_serialization.h" #include "content/common/view_messages.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui_controller_factory.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/content_switches.h" #include "content/public/common/page_zoom.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" #include "content/public/renderer/document_state.h" #include "content/public/renderer/history_item_serialization.h" #include "content/public/renderer/navigation_state.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/render_view_test.h" +#include "content/public/test/test_utils.h" #include "content/renderer/render_view_impl.h" +#include "content/shell/browser/shell.h" +#include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_content_browser_client.h" #include "content/shell/common/shell_content_client.h" +#include "content/shell/renderer/shell_content_renderer_client.h" +#include "content/test/content_browser_test.h" +#include "content/test/content_browser_test_utils.h" #include "content/test/mock_keyboard.h" #include "net/base/net_errors.h" #include "net/cert/cert_status_flags.h" +#include "net/disk_cache/disk_cache.h" +#include "net/http/failing_http_transaction_factory.h" +#include "net/http/http_cache.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebData.h" #include "third_party/WebKit/public/platform/WebHTTPBody.h" @@ -118,8 +138,6 @@ class WebUITestWebUIControllerFactory : public WebUIControllerFactory { } }; -} // namespace - class RenderViewImplTest : public RenderViewTest { public: RenderViewImplTest() { @@ -305,6 +323,99 @@ class RenderViewImplTest : public RenderViewTest { scoped_ptr<MockKeyboard> mock_keyboard_; }; +class TestShellContentRendererClient : public ShellContentRendererClient { + public: + TestShellContentRendererClient() + : latest_error_valid_(false), + latest_error_reason_(0), + latest_error_stale_copy_in_cache_(false) {} + + virtual void GetNavigationErrorStrings( + content::RenderView* render_view, + blink::WebFrame* frame, + const blink::WebURLRequest& failed_request, + const blink::WebURLError& error, + std::string* error_html, + base::string16* error_description) OVERRIDE { + if (error_html) + *error_html = "A suffusion of yellow."; + latest_error_valid_ = true; + latest_error_reason_ = error.reason; + latest_error_stale_copy_in_cache_ = error.staleCopyInCache; + } + + bool GetLatestError(int* error_code, bool* stale_cache_entry_present) { + if (latest_error_valid_) { + *error_code = latest_error_reason_; + *stale_cache_entry_present = latest_error_stale_copy_in_cache_; + } + return latest_error_valid_; + } + + private: + bool latest_error_valid_; + int latest_error_reason_; + bool latest_error_stale_copy_in_cache_; +}; + +// Must be called on IO thread. +void InterceptNetworkTransactions(net::URLRequestContextGetter* getter, + net::Error error) { + DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); + net::HttpCache* cache( + getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); + DCHECK(cache); + scoped_ptr<net::FailingHttpTransactionFactory> factory( + new net::FailingHttpTransactionFactory(cache->GetSession(), error)); + // Throw away old version; since this is a browser test, there is no + // need to restore the old state. + cache->SetHttpNetworkTransactionFactoryForTesting( + factory.PassAs<net::HttpTransactionFactory>()); +} + +void CallOnUIThreadValidatingReturn(const base::Closure& callback, + int rv) { + DCHECK_EQ(net::OK, rv); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, callback); +} + +// Must be called on IO thread. The callback will be called on +// completion of cache clearing on the UI thread. +void BackendClearCache(scoped_ptr<disk_cache::Backend*> backend, + const base::Closure& callback, + int rv) { + DCHECK(*backend); + DCHECK_EQ(net::OK, rv); + (*backend)->DoomAllEntries( + base::Bind(&CallOnUIThreadValidatingReturn, callback)); +} + +// Must be called on IO thread. The callback will be called on +// completion of cache clearing on the UI thread. +void ClearCache(net::URLRequestContextGetter* getter, + const base::Closure& callback) { + DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); + net::HttpCache* cache( + getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); + DCHECK(cache); + scoped_ptr<disk_cache::Backend*> backend(new disk_cache::Backend*); + *backend = NULL; + disk_cache::Backend** backend_ptr = backend.get(); + + net::CompletionCallback backend_callback( + base::Bind(&BackendClearCache, base::Passed(backend.Pass()), callback)); + + // backend_ptr is valid until all copies of backend_callback go out + // of scope. + if (net::OK == cache->GetBackend(backend_ptr, backend_callback)) { + // The call completed synchronously, so GetBackend didn't run the callback. + backend_callback.Run(net::OK); + } +} + +} // namespace + // Test that we get form state change notifications when input fields change. TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) { // Don't want any delay for form state sync changes. This will still post a @@ -2243,4 +2354,114 @@ TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) { render_thread_->sink().ClearMessages(); } +// For actual, browser side tests targetting code in RenderView +// or RenderViewImpl. +class RenderViewBrowserTest : public ContentBrowserTest { + public: + RenderViewBrowserTest() : renderer_client_(NULL) {} + + virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { + // This method is needed to allow interaction with in-process renderer + // and use of a test ContentRendererClient. + command_line->AppendSwitch(switches::kSingleProcess); + } + + virtual void SetUp() OVERRIDE { + // Override setting of renderer client. + renderer_client_ = new TestShellContentRendererClient(); + SetContentRendererClient( + scoped_ptr<ContentRendererClient>(renderer_client_).Pass()); + + ContentBrowserTest::SetUp(); + } + + // Navigates to the given URL and waits for |num_navigations| to occur, and + // the title to change to |expected_title|. + void NavigateToURLAndWaitForTitle(const GURL& url, + const std::string& expected_title, + int num_navigations) { + content::TitleWatcher title_watcher( + shell()->web_contents(), base::ASCIIToUTF16(expected_title)); + + content::NavigateToURLBlockUntilNavigationsComplete( + shell(), url, num_navigations); + + EXPECT_EQ(base::ASCIIToUTF16(expected_title), + title_watcher.WaitAndGetTitle()); + } + + // Returns true if there is a valid error stored; in this case + // |*error_code| and |*stale_cache_entry_present| will be updated + // appropriately. + // Must be called after the renderer thread is created. + bool GetLatestErrorFromRendererClient( + int* error_code, bool* stale_cache_entry_present) { + bool result = false; + + PostTaskToInProcessRendererAndWait( + base::Bind(&RenderViewBrowserTest::GetLatestErrorFromRendererClient0, + renderer_client_, &result, error_code, + stale_cache_entry_present)); + return result; + } + + private: + // Must be run on renderer thread. + static void GetLatestErrorFromRendererClient0( + TestShellContentRendererClient* renderer_client, + bool* result, int* error_code, bool* stale_cache_entry_present) { + *result = renderer_client->GetLatestError( + error_code, stale_cache_entry_present); + } + + // Actually owned by the superclass, so safe to keep a bare pointer. + TestShellContentRendererClient* renderer_client_; +}; + +IN_PROC_BROWSER_TEST_F(RenderViewBrowserTest, ConfirmCacheInformationPlumbed) { + ASSERT_TRUE(test_server()->Start()); + + // Load URL 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. + int renderer_id = + shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(); + scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = + ShellContentBrowserClient::Get()->browser_context()-> + GetRequestContextForRenderProcess(renderer_id); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&InterceptNetworkTransactions, url_request_context_getter, + net::ERR_FAILED)); + + // An error results in one completed navigation. + content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); + int error_code = net::OK; + bool stale_cache_entry_present = false; + ASSERT_TRUE(GetLatestErrorFromRendererClient( + &error_code, &stale_cache_entry_present)); + EXPECT_EQ(net::ERR_FAILED, error_code); + EXPECT_TRUE(stale_cache_entry_present); + + // Clear the cache and repeat; confirm lack of entry in cache reported. + scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ClearCache, url_request_context_getter, + runner->QuitClosure())); + runner->Run(); + + content::NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 1); + + error_code = net::OK; + stale_cache_entry_present = true; + ASSERT_TRUE(GetLatestErrorFromRendererClient( + &error_code, &stale_cache_entry_present)); + EXPECT_EQ(net::ERR_FAILED, error_code); + EXPECT_FALSE(stale_cache_entry_present); +} + } // namespace content diff --git a/content/test/content_browser_test.cc b/content/test/content_browser_test.cc index a164450..3881613 100644 --- a/content/test/content_browser_test.cc +++ b/content/test/content_browser_test.cc @@ -55,8 +55,6 @@ ContentBrowserTest::~ContentBrowserTest() { } void ContentBrowserTest::SetUp() { - setup_called_ = true; - shell_main_delegate_.reset(new ShellMainDelegate); shell_main_delegate_->PreSandboxStartup(); @@ -65,11 +63,16 @@ void ContentBrowserTest::SetUp() { SetUpCommandLine(command_line); - // Single-process mode is not set in BrowserMain, so process it explicitly, - // and set up renderer. + // Single-process mode is not set in BrowserMain, so if a subclass hasn't + // modified it yet, process it explicitly, and set up renderer. if (command_line->HasSwitch(switches::kSingleProcess)) { - single_process_renderer_client_.reset(new ShellContentRendererClient); + if (!single_process_renderer_client_) + single_process_renderer_client_.reset(new ShellContentRendererClient()); SetRendererClientForTesting(single_process_renderer_client_.get()); + } else { + // Confirm no test has called SetContentRendererClient() without + // setting up single process mode. + DCHECK(!single_process_renderer_client_); } #if defined(OS_MACOSX) @@ -89,6 +92,8 @@ void ContentBrowserTest::SetUp() { ui::InitializeInputMethodForTesting(); #endif + setup_called_ = true; + BrowserTestBase::SetUp(); } @@ -144,6 +149,14 @@ void ContentBrowserTest::RunTestOnMainThreadLoop() { Shell::CloseAllWindows(); } +void ContentBrowserTest::SetContentRendererClient( + scoped_ptr<ContentRendererClient> renderer_client) { + // This routine must be called before SetUp(). + DCHECK(!setup_called_); + DCHECK(!single_process_renderer_client_); + single_process_renderer_client_ = renderer_client.Pass(); +} + Shell* ContentBrowserTest::CreateBrowser() { return Shell::CreateNewWindow( ShellContentBrowserClient::Get()->browser_context(), diff --git a/content/test/content_browser_test.h b/content/test/content_browser_test.h index 5a76bb6..0647d4a 100644 --- a/content/test/content_browser_test.h +++ b/content/test/content_browser_test.h @@ -28,6 +28,10 @@ class ContentBrowserTest : public BrowserTestBase { // BrowserTestBase: virtual void RunTestOnMainThreadLoop() OVERRIDE; + // Must be called before or during setup. + void SetContentRendererClient( + scoped_ptr<ContentRendererClient> renderer_client); + protected: // Creates a new window and loads about:blank. Shell* CreateBrowser(); diff --git a/content/test/data/nocache.html b/content/test/data/nocache.html new file mode 100644 index 0000000..9ef8195 --- /dev/null +++ b/content/test/data/nocache.html @@ -0,0 +1,4 @@ +<html> +<head><title>Nocache Test Page</title></head> +<body>Nocache test body</body> +</html> diff --git a/content/test/data/nocache.html.mock-http-headers b/content/test/data/nocache.html.mock-http-headers new file mode 100644 index 0000000..a52ff3d --- /dev/null +++ b/content/test/data/nocache.html.mock-http-headers @@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +Cache-Control: nocache |