summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-17 15:02:38 +0000
committertburkard@chromium.org <tburkard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-17 15:02:38 +0000
commit798da0547e4e981a5ae2b3fdc5d6f0798321b261 (patch)
tree4a34af31f6a50edf6564a7cccc2d9c49426675aa
parent0299de3455f7ba3dfdee77625e0f8696e8075ba7 (diff)
downloadchromium_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.cc84
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/common/common_message_generator.h1
-rw-r--r--chrome/common/prefetch_messages.h19
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc3
-rw-r--r--chrome/renderer/prefetch_helper.cc58
-rw-r--r--chrome/renderer/prefetch_helper.h44
-rw-r--r--ipc/ipc_message_start.h1
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,