diff options
author | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 15:02:38 +0000 |
---|---|---|
committer | tburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 15:02:38 +0000 |
commit | 798da0547e4e981a5ae2b3fdc5d6f0798321b261 (patch) | |
tree | 4a34af31f6a50edf6564a7cccc2d9c49426675aa | |
parent | 0299de3455f7ba3dfdee77625e0f8696e8075ba7 (diff) | |
download | chromium_src-798da0547e4e981a5ae2b3fdc5d6f0798321b261.zip chromium_src-798da0547e4e981a5ae2b3fdc5d6f0798321b261.tar.gz chromium_src-798da0547e4e981a5ae2b3fdc5d6f0798321b261.tar.bz2 |
Enable resource prefetch from the browser process.
R=jam@chromium.org, jochen@chromium.org, jschuh@chromium.org
Review URL: https://codereview.chromium.org/334483004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277761 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/prefetch/prefetch_browsertest.cc | 84 | ||||
-rw-r--r-- | chrome/chrome_renderer.gypi | 2 | ||||
-rw-r--r-- | chrome/common/common_message_generator.h | 1 | ||||
-rw-r--r-- | chrome/common/prefetch_messages.h | 19 | ||||
-rw-r--r-- | chrome/renderer/chrome_content_renderer_client.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/prefetch_helper.cc | 58 | ||||
-rw-r--r-- | chrome/renderer/prefetch_helper.h | 44 | ||||
-rw-r--r-- | ipc/ipc_message_start.h | 1 |
8 files changed, 205 insertions, 7 deletions
diff --git a/chrome/browser/prefetch/prefetch_browsertest.cc b/chrome/browser/prefetch/prefetch_browsertest.cc index a870be6..bd24ad2 100644 --- a/chrome/browser/prefetch/prefetch_browsertest.cc +++ b/chrome/browser/prefetch/prefetch_browsertest.cc @@ -4,15 +4,23 @@ #include "base/command_line.h" #include "base/prefs/pref_service.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chrome/common/prefetch_messages.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/browser_test_utils.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_job.h" + +using content::BrowserThread; namespace { @@ -27,13 +35,11 @@ class PrefetchBrowserTestBase : public InProcessBrowserTest { virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { if (do_prefetch_field_trial_) { - command_line->AppendSwitchASCII( - switches::kForceFieldTrials, - "Prefetch/ExperimentYes/"); + command_line->AppendSwitchASCII(switches::kForceFieldTrials, + "Prefetch/ExperimentYes/"); } else { - command_line->AppendSwitchASCII( - switches::kForceFieldTrials, - "Prefetch/ExperimentNo/"); + command_line->AppendSwitchASCII(switches::kForceFieldTrials, + "Prefetch/ExperimentNo/"); } } @@ -84,6 +90,50 @@ class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase { : PrefetchBrowserTestBase(false, false) {} }; +// URLRequestJob (and associated handler) which hangs. +class HangingURLRequestJob : public net::URLRequestJob { + public: + HangingURLRequestJob(net::URLRequest* request, + net::NetworkDelegate* network_delegate) + : net::URLRequestJob(request, network_delegate) {} + + // net::URLRequestJob implementation + virtual void Start() OVERRIDE {} + + private: + virtual ~HangingURLRequestJob() {} + + DISALLOW_COPY_AND_ASSIGN(HangingURLRequestJob); +}; + +class HangingRequestInterceptor : public net::URLRequestInterceptor { + public: + explicit HangingRequestInterceptor(const base::Closure& callback) + : callback_(callback) {} + + virtual ~HangingRequestInterceptor() {} + + virtual net::URLRequestJob* MaybeInterceptRequest( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const OVERRIDE { + if (!callback_.is_null()) + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback_); + return new HangingURLRequestJob(request, network_delegate); + } + + private: + base::Closure callback_; +}; + +void CreateHangingRequestInterceptorOnIO(const GURL& url, + base::Closure callback) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + scoped_ptr<net::URLRequestInterceptor> never_respond_handler( + new HangingRequestInterceptor(callback)); + net::URLRequestFilter::GetInstance()->AddUrlInterceptor( + url, never_respond_handler.Pass()); +} + // Privacy option is on, experiment is on. Prefetch should succeed. IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) { EXPECT_TRUE(RunPrefetchExperiment(true, browser())); @@ -118,5 +168,25 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, IncognitoTest) { EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser)); } -} // namespace +// This test will verify the following: +// - that prefetches from the browser are actually launched +// - if a prefetch is in progress, but the originating renderer is destroyed, +// that the pending prefetch request is cleaned up cleanly and does not +// result in a crash. +IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, + PrefetchFromBrowser) { + const GURL kHangingUrl("http://hanging-url.com"); + base::RunLoop loop_; + BrowserThread::PostTask(BrowserThread::IO, + FROM_HERE, + base::Bind(&CreateHangingRequestInterceptorOnIO, + kHangingUrl, + loop_.QuitClosure())); + ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + content::RenderFrameHost* rfh = + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); + rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), kHangingUrl)); + loop_.Run(); +} +} // namespace diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index ca431d9..b817ebd 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -212,6 +212,8 @@ 'renderer/plugins/chrome_plugin_placeholder.h', 'renderer/plugins/plugin_uma.cc', 'renderer/plugins/plugin_uma.h', + 'renderer/prefetch_helper.cc', + 'renderer/prefetch_helper.h', 'renderer/prerender/prerender_dispatcher.cc', 'renderer/prerender/prerender_dispatcher.h', 'renderer/prerender/prerender_extra_data.cc', diff --git a/chrome/common/common_message_generator.h b/chrome/common/common_message_generator.h index 02ecfe3..37cd6d5 100644 --- a/chrome/common/common_message_generator.h +++ b/chrome/common/common_message_generator.h @@ -9,6 +9,7 @@ #include "chrome/common/cast_messages.h" #include "chrome/common/chrome_utility_messages.h" #include "chrome/common/extensions/chrome_extension_messages.h" +#include "chrome/common/prefetch_messages.h" #include "chrome/common/prerender_messages.h" #include "chrome/common/render_messages.h" #include "chrome/common/safe_browsing/safebrowsing_messages.h" diff --git a/chrome/common/prefetch_messages.h b/chrome/common/prefetch_messages.h new file mode 100644 index 0000000..e4f691a --- /dev/null +++ b/chrome/common/prefetch_messages.h @@ -0,0 +1,19 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Multiply-included message file, no traditional include guard. +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ipc/ipc_param_traits.h" +#include "url/gurl.h" + +#define IPC_MESSAGE_START PrefetchMsgStart + +// Prefetch Messages +// These are messages sent from the browser to the renderer related to +// prefetching. + +// Instructs the renderer to launch a prefetch within its context. +IPC_MESSAGE_ROUTED1(PrefetchMsg_Prefetch, + GURL /* url */) diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index dbd4972..f3e2313 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -51,6 +51,7 @@ #include "chrome/renderer/playback_extension.h" #include "chrome/renderer/plugins/chrome_plugin_placeholder.h" #include "chrome/renderer/plugins/plugin_uma.h" +#include "chrome/renderer/prefetch_helper.h" #include "chrome/renderer/prerender/prerender_dispatcher.h" #include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerender_media_load_deferrer.h" @@ -423,7 +424,9 @@ void ChromeContentRendererClient::RenderFrameCreated( if (render_frame->GetRenderView()->GetMainRenderFrame() == render_frame) { // Only attach NetErrorHelper to the main frame, since only the main frame // should get error pages. + // PrefetchHelper is also needed only for main frames. new NetErrorHelper(render_frame); + new prefetch::PrefetchHelper(render_frame); } } diff --git a/chrome/renderer/prefetch_helper.cc b/chrome/renderer/prefetch_helper.cc new file mode 100644 index 0000000..ee0d439 --- /dev/null +++ b/chrome/renderer/prefetch_helper.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/prefetch_helper.h" + +#include "chrome/common/prefetch_messages.h" +#include "content/public/renderer/render_frame.h" +#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebURLLoaderOptions.h" + +namespace prefetch { + +PrefetchHelper::PrefetchHelper(content::RenderFrame* render_frame) + : content::RenderFrameObserver(render_frame) { +} + +PrefetchHelper::~PrefetchHelper() { + STLDeleteElements(&loader_set_); +} + +bool PrefetchHelper::OnMessageReceived( + const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PrefetchHelper, message) + IPC_MESSAGE_HANDLER(PrefetchMsg_Prefetch, OnPrefetch) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +void PrefetchHelper::OnPrefetch(const GURL& url) { + blink::WebFrame* frame = render_frame()->GetWebFrame(); + blink::WebURLRequest request(url); + request.setTargetType(blink::WebURLRequest::TargetIsPrefetch); + request.setPriority(blink::WebURLRequest::PriorityVeryLow); + blink::WebURLLoaderOptions options; + options.allowCredentials = true; + options.crossOriginRequestPolicy = + blink::WebURLLoaderOptions::CrossOriginRequestPolicyAllow; + blink::WebURLLoader* loader = frame->createAssociatedURLLoader(options); + loader->loadAsynchronously(request, this); + loader_set_.insert(loader); +} + +void PrefetchHelper::didFinishLoading(blink::WebURLLoader* loader, + double finishTime, + int64_t totalEncodedDataLength) { + loader_set_.erase(loader); +} + +void PrefetchHelper::didFail(blink::WebURLLoader* loader, + const blink::WebURLError& error) { + loader_set_.erase(loader); +} + +} // namespace prefetch diff --git a/chrome/renderer/prefetch_helper.h b/chrome/renderer/prefetch_helper.h new file mode 100644 index 0000000..2c74e01 --- /dev/null +++ b/chrome/renderer/prefetch_helper.h @@ -0,0 +1,44 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_PREFETCH_HELPER_H_ +#define CHROME_RENDERER_PREFETCH_HELPER_H_ + +#include <set> + +#include "content/public/renderer/render_frame_observer.h" +#include "third_party/WebKit/public/platform/WebURLLoader.h" +#include "third_party/WebKit/public/platform/WebURLLoaderClient.h" +#include "url/gurl.h" + +namespace prefetch { + +// Helper class initiating prefetches on behalf of a RenderFrame. +class PrefetchHelper : public content::RenderFrameObserver, + public blink::WebURLLoaderClient { + public: + explicit PrefetchHelper(content::RenderFrame* render_frame); + virtual ~PrefetchHelper(); + + // blink::WebURLLoaderClient implementation + virtual void didFinishLoading(blink::WebURLLoader* loader, + double finishTime, + int64_t totalEncodedDataLength) OVERRIDE; + virtual void didFail(blink::WebURLLoader* loader, + const blink::WebURLError& error) OVERRIDE; + + private: + // RenderViewObserver implementation + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + void OnPrefetch(const GURL& url); + + std::set<blink::WebURLLoader*> loader_set_; + + DISALLOW_COPY_AND_ASSIGN(PrefetchHelper); +}; + +} // namespace prefetch + +#endif // CHROME_RENDERER_PREFETCH_HELPER_H_ diff --git a/ipc/ipc_message_start.h b/ipc/ipc_message_start.h index 337b1aa..48ed244 100644 --- a/ipc/ipc_message_start.h +++ b/ipc/ipc_message_start.h @@ -66,6 +66,7 @@ enum IPCMessageStart { GamepadMsgStart, ShellMsgStart, AccessibilityMsgStart, + PrefetchMsgStart, PrerenderMsgStart, ChromotingMsgStart, OldBrowserPluginMsgStart, |