Commit d52474c3 authored by Egor Pasko's avatar Egor Pasko Committed by Commit Bot

NoStatePrefetch: Add Purpose:prefetch header

The header should be set for all requests originating from
nostate-prefetch, main resource, all redirects and all subresources.

Using base::BindRepeating in new tests because of presubmit
warning, also switched similar tests to it for consistency.

Bug: 796855
Change-Id: I90614fac595f2dbc087a6ac99f54e2fc7d37f89a
Reviewed-on: https://chromium-review.googlesource.com/1104692
Commit-Queue: Egor Pasko <pasko@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarMatthew Cary <mattcary@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568409}
parent 035ce793
......@@ -144,6 +144,7 @@
#include "chrome/common/pepper_permission_util.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/prerender_url_loader_throttle.h"
#include "chrome/common/prerender_util.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/renderer_configuration.mojom.h"
#include "chrome/common/secure_origin_whitelist.h"
......@@ -2152,9 +2153,13 @@ void ChromeContentBrowserClient::NavigationRequestStarted(
web_contents->GetBrowserContext(), url);
prerender::PrerenderContents* prerender_contents =
prerender::PrerenderContents::FromWebContents(web_contents);
if (prerender_contents) {
if (prerender_contents->prerender_mode() == prerender::PREFETCH_ONLY)
*extra_load_flags = net::LOAD_PREFETCH;
if (prerender_contents &&
prerender_contents->prerender_mode() == prerender::PREFETCH_ONLY) {
*extra_load_flags = net::LOAD_PREFETCH;
if (*extra_headers == nullptr)
*extra_headers = std::make_unique<net::HttpRequestHeaders>();
extra_headers->get()->SetHeader(prerender::kPurposeHeaderName,
prerender::kPurposeHeaderValue);
}
}
......
......@@ -54,6 +54,12 @@ using prerender::test_utils::DestructionWaiter;
using prerender::test_utils::RequestCounter;
using prerender::test_utils::TestPrerender;
namespace {
const char kExpectedPurposeHeaderOnPrefetch[] = "Purpose";
} // namespace
namespace prerender {
const char k302RedirectPage[] = "/prerender/302_redirect.html";
......@@ -257,7 +263,7 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchLoadFlag) {
GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
GURL prefetch_script = src_server()->GetURL(kPrefetchScript);
content::URLLoaderInterceptor interceptor(base::Bind(
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](const GURL& prefetch_page, const GURL& prefetch_script,
content::URLLoaderInterceptor::RequestParams* params) {
if (params->url_request.url == prefetch_page ||
......@@ -277,6 +283,63 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchLoadFlag) {
test_prerender->WaitForLoads(0);
}
// Check that prefetched resources and subresources set the 'Purpose: prefetch'
// header.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PurposeHeaderIsSet) {
GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
GURL prefetch_script = src_server()->GetURL(kPrefetchScript);
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](const GURL& prefetch_page, const GURL& prefetch_script,
content::URLLoaderInterceptor::RequestParams* params) {
if (params->url_request.url == prefetch_page ||
params->url_request.url == prefetch_script) {
EXPECT_TRUE(params->url_request.load_flags & net::LOAD_PREFETCH);
EXPECT_TRUE(params->url_request.headers.HasHeader(
kExpectedPurposeHeaderOnPrefetch));
std::string purpose_header;
params->url_request.headers.GetHeader(
kExpectedPurposeHeaderOnPrefetch, &purpose_header);
EXPECT_EQ("prefetch", purpose_header);
}
return false;
},
prefetch_page, prefetch_script));
std::unique_ptr<TestPrerender> test_prerender =
PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);
WaitForRequestCount(prefetch_page, 1);
WaitForRequestCount(prefetch_script, 1);
}
// Check that on normal navigations the 'Purpose: prefetch' header is not set.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
PurposeHeaderNotSetWhenNotPrefetching) {
GURL prefetch_page = src_server()->GetURL(kPrefetchPage);
GURL prefetch_script = src_server()->GetURL(kPrefetchScript);
GURL prefetch_script2 = src_server()->GetURL(kPrefetchScript2);
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](const GURL& prefetch_page, const GURL& prefetch_script,
const GURL& prefetch_script2,
content::URLLoaderInterceptor::RequestParams* params) {
if (params->url_request.url == prefetch_page ||
params->url_request.url == prefetch_script ||
params->url_request.url == prefetch_script2) {
EXPECT_FALSE(params->url_request.load_flags & net::LOAD_PREFETCH);
EXPECT_FALSE(params->url_request.headers.HasHeader(
kExpectedPurposeHeaderOnPrefetch));
}
return false;
},
prefetch_page, prefetch_script, prefetch_script2));
ui_test_utils::NavigateToURL(current_browser(), prefetch_page);
WaitForRequestCount(prefetch_page, 1);
WaitForRequestCount(prefetch_script, 1);
WaitForRequestCount(prefetch_script2, 1);
}
// Check that a prefetch followed by a load produces the approriate
// histograms. Note that other histogram testing is done in
// browser/page_load_metrics, in particular, testing the combinations of
......@@ -411,11 +474,7 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, Prefetch301LoadFlags) {
"/server-redirect/?" + net::EscapeQueryParamValue(kPrefetchPage, false);
GURL redirect_url = src_server()->GetURL(redirect_path);
GURL page_url = src_server()->GetURL(kPrefetchPage);
auto verify_prefetch_only = base::Bind([](net::URLRequest* request) {
EXPECT_TRUE(request->load_flags() & net::LOAD_PREFETCH);
});
content::URLLoaderInterceptor interceptor(base::Bind(
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](const GURL& page_url,
content::URLLoaderInterceptor::RequestParams* params) {
if (params->url_request.url == page_url)
......
......@@ -131,6 +131,7 @@ void PrerenderURLLoaderThrottle::WillStartRequest(
#endif // OS_ANDROID
if (mode_ == PREFETCH_ONLY) {
request->headers.SetHeader(kPurposeHeaderName, kPurposeHeaderValue);
detached_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(
content::kDefaultDetachableCancelDelayMs),
......
......@@ -46,6 +46,8 @@ int GetResourceType(bool is_main_resource, bool is_redirect, bool is_no_store) {
} // namespace
const char kFollowOnlyWhenPrerenderShown[] = "follow-only-when-prerender-shown";
const char kPurposeHeaderName[] = "Purpose";
const char kPurposeHeaderValue[] = "prefetch";
bool DoesURLHaveValidScheme(const GURL& url) {
return (url.SchemeIsHTTPOrHTTPS() ||
......
......@@ -13,6 +13,8 @@ class GURL;
namespace prerender {
extern const char kFollowOnlyWhenPrerenderShown[];
extern const char kPurposeHeaderName[];
extern const char kPurposeHeaderValue[];
// Returns true iff the scheme of the URL given is valid for prerendering.
bool DoesURLHaveValidScheme(const GURL& url);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment