Commit 2b09e25d authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

Create a per-pageload member encapsulation for IsolatedPrerenderTH

Adds a new private class which holds all the members for the tab helper
that need to be reset on every page load.
The encapsulating class is always initialized to keep the diff and logic
change to a minimum.

Bug: 1023483
Change-Id: I1c91ce7eb3d65937e35fcbd949c8d81907adc8f8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2097035
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748832}
parent d6908793
...@@ -35,9 +35,13 @@ ...@@ -35,9 +35,13 @@
#include "services/network/public/mojom/cookie_manager.mojom.h" #include "services/network/public/mojom/cookie_manager.mojom.h"
#include "url/origin.h" #include "url/origin.h"
IsolatedPrerenderTabHelper::CurrentPageLoad::CurrentPageLoad() = default;
IsolatedPrerenderTabHelper::CurrentPageLoad::~CurrentPageLoad() = default;
IsolatedPrerenderTabHelper::IsolatedPrerenderTabHelper( IsolatedPrerenderTabHelper::IsolatedPrerenderTabHelper(
content::WebContents* web_contents) content::WebContents* web_contents)
: content::WebContentsObserver(web_contents) { : content::WebContentsObserver(web_contents) {
page_ = std::make_unique<CurrentPageLoad>();
profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
url_loader_factory_ = url_loader_factory_ =
content::BrowserContext::GetDefaultStoragePartition(profile_) content::BrowserContext::GetDefaultStoragePartition(profile_)
...@@ -75,7 +79,7 @@ void IsolatedPrerenderTabHelper::DidStartNavigation( ...@@ -75,7 +79,7 @@ void IsolatedPrerenderTabHelper::DidStartNavigation(
} }
// User is navigating, don't bother prefetching further. // User is navigating, don't bother prefetching further.
url_loader_.reset(); page_->url_loader.reset();
} }
void IsolatedPrerenderTabHelper::DidFinishNavigation( void IsolatedPrerenderTabHelper::DidFinishNavigation(
...@@ -92,26 +96,24 @@ void IsolatedPrerenderTabHelper::DidFinishNavigation( ...@@ -92,26 +96,24 @@ void IsolatedPrerenderTabHelper::DidFinishNavigation(
} }
DCHECK(!PrefetchingActive()); DCHECK(!PrefetchingActive());
urls_to_prefetch_.clear(); page_ = std::make_unique<CurrentPageLoad>();
prefetched_responses_.clear();
num_prefetches_attempted_ = 0;
} }
std::unique_ptr<PrefetchedMainframeResponseContainer> std::unique_ptr<PrefetchedMainframeResponseContainer>
IsolatedPrerenderTabHelper::TakePrefetchResponse(const GURL& url) { IsolatedPrerenderTabHelper::TakePrefetchResponse(const GURL& url) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = prefetched_responses_.find(url); auto it = page_->prefetched_responses.find(url);
if (it == prefetched_responses_.end()) if (it == page_->prefetched_responses.end())
return nullptr; return nullptr;
std::unique_ptr<PrefetchedMainframeResponseContainer> response = std::unique_ptr<PrefetchedMainframeResponseContainer> response =
std::move(it->second); std::move(it->second);
prefetched_responses_.erase(it); page_->prefetched_responses.erase(it);
return response; return response;
} }
bool IsolatedPrerenderTabHelper::PrefetchingActive() const { bool IsolatedPrerenderTabHelper::PrefetchingActive() const {
return !!url_loader_; return page_ && page_->url_loader;
} }
void IsolatedPrerenderTabHelper::Prefetch() { void IsolatedPrerenderTabHelper::Prefetch() {
...@@ -119,20 +121,20 @@ void IsolatedPrerenderTabHelper::Prefetch() { ...@@ -119,20 +121,20 @@ void IsolatedPrerenderTabHelper::Prefetch() {
DCHECK(base::FeatureList::IsEnabled( DCHECK(base::FeatureList::IsEnabled(
features::kPrefetchSRPNavigationPredictions_HTMLOnly)); features::kPrefetchSRPNavigationPredictions_HTMLOnly));
url_loader_.reset(); page_->url_loader.reset();
if (urls_to_prefetch_.empty()) { if (page_->urls_to_prefetch.empty()) {
return; return;
} }
if (IsolatedPrerenderMaximumNumberOfPrefetches().has_value() && if (IsolatedPrerenderMaximumNumberOfPrefetches().has_value() &&
num_prefetches_attempted_ >= page_->num_prefetches_attempted >=
IsolatedPrerenderMaximumNumberOfPrefetches().value()) { IsolatedPrerenderMaximumNumberOfPrefetches().value()) {
return; return;
} }
num_prefetches_attempted_++; page_->num_prefetches_attempted++;
GURL url = urls_to_prefetch_[0]; GURL url = page_->urls_to_prefetch[0];
urls_to_prefetch_.erase(urls_to_prefetch_.begin()); page_->urls_to_prefetch.erase(page_->urls_to_prefetch.begin());
std::unique_ptr<network::ResourceRequest> request = std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>(); std::make_unique<network::ResourceRequest>();
...@@ -169,14 +171,14 @@ void IsolatedPrerenderTabHelper::Prefetch() { ...@@ -169,14 +171,14 @@ void IsolatedPrerenderTabHelper::Prefetch() {
// TODO(crbug/1023485): Disallow auth challenges. // TODO(crbug/1023485): Disallow auth challenges.
url_loader_ = page_->url_loader =
network::SimpleURLLoader::Create(std::move(request), traffic_annotation); network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
// base::Unretained is safe because |url_loader_| is owned by |this|. // base::Unretained is safe because |page_->url_loader| is owned by |this|.
url_loader_->SetOnRedirectCallback(base::BindRepeating( page_->url_loader->SetOnRedirectCallback(base::BindRepeating(
&IsolatedPrerenderTabHelper::OnPrefetchRedirect, base::Unretained(this))); &IsolatedPrerenderTabHelper::OnPrefetchRedirect, base::Unretained(this)));
url_loader_->SetAllowHttpErrorResults(true); page_->url_loader->SetAllowHttpErrorResults(true);
url_loader_->DownloadToString( page_->url_loader->DownloadToString(
url_loader_factory_.get(), url_loader_factory_.get(),
base::BindOnce(&IsolatedPrerenderTabHelper::OnPrefetchComplete, base::BindOnce(&IsolatedPrerenderTabHelper::OnPrefetchComplete,
base::Unretained(this), url), base::Unretained(this), url),
...@@ -193,7 +195,7 @@ void IsolatedPrerenderTabHelper::OnPrefetchRedirect( ...@@ -193,7 +195,7 @@ void IsolatedPrerenderTabHelper::OnPrefetchRedirect(
if (CheckAndMaybePrefetchURL(redirect_info.new_url)) { if (CheckAndMaybePrefetchURL(redirect_info.new_url)) {
// The redirect shouldn't count against our prefetch limit if the redirect // The redirect shouldn't count against our prefetch limit if the redirect
// was followed. // was followed.
num_prefetches_attempted_--; page_->num_prefetches_attempted--;
} }
// Cancels the current request. // Cancels the current request.
Prefetch(); Prefetch();
...@@ -205,10 +207,10 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete( ...@@ -205,10 +207,10 @@ void IsolatedPrerenderTabHelper::OnPrefetchComplete(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(PrefetchingActive()); DCHECK(PrefetchingActive());
if (url_loader_->NetError() == net::OK && body && if (page_->url_loader->NetError() == net::OK && body &&
url_loader_->ResponseInfo()) { page_->url_loader->ResponseInfo()) {
network::mojom::URLResponseHeadPtr head = network::mojom::URLResponseHeadPtr head =
url_loader_->ResponseInfo()->Clone(); page_->url_loader->ResponseInfo()->Clone();
HandlePrefetchResponse(url, std::move(head), std::move(body)); HandlePrefetchResponse(url, std::move(head), std::move(body));
} }
Prefetch(); Prefetch();
...@@ -232,7 +234,7 @@ void IsolatedPrerenderTabHelper::HandlePrefetchResponse( ...@@ -232,7 +234,7 @@ void IsolatedPrerenderTabHelper::HandlePrefetchResponse(
std::unique_ptr<PrefetchedMainframeResponseContainer> response = std::unique_ptr<PrefetchedMainframeResponseContainer> response =
std::make_unique<PrefetchedMainframeResponseContainer>(std::move(head), std::make_unique<PrefetchedMainframeResponseContainer>(std::move(head),
std::move(body)); std::move(body));
prefetched_responses_.emplace(url, std::move(response)); page_->prefetched_responses.emplace(url, std::move(response));
} }
void IsolatedPrerenderTabHelper::OnPredictionUpdated( void IsolatedPrerenderTabHelper::OnPredictionUpdated(
...@@ -260,7 +262,7 @@ void IsolatedPrerenderTabHelper::OnPredictionUpdated( ...@@ -260,7 +262,7 @@ void IsolatedPrerenderTabHelper::OnPredictionUpdated(
// again here allows us to skip querying for cookies if we won't be // again here allows us to skip querying for cookies if we won't be
// prefetching the url anyways. // prefetching the url anyways.
if (IsolatedPrerenderMaximumNumberOfPrefetches().has_value() && if (IsolatedPrerenderMaximumNumberOfPrefetches().has_value() &&
num_prefetches_attempted_ >= page_->num_prefetches_attempted >=
IsolatedPrerenderMaximumNumberOfPrefetches().value()) { IsolatedPrerenderMaximumNumberOfPrefetches().value()) {
return; return;
} }
...@@ -343,7 +345,7 @@ void IsolatedPrerenderTabHelper::OnGotCookieList( ...@@ -343,7 +345,7 @@ void IsolatedPrerenderTabHelper::OnGotCookieList(
return; return;
// TODO(robertogden): Consider adding redirect URLs to the front of the list. // TODO(robertogden): Consider adding redirect URLs to the front of the list.
urls_to_prefetch_.push_back(url); page_->urls_to_prefetch.push_back(url);
if (!PrefetchingActive()) { if (!PrefetchingActive()) {
Prefetch(); Prefetch();
......
...@@ -39,7 +39,7 @@ class IsolatedPrerenderTabHelper ...@@ -39,7 +39,7 @@ class IsolatedPrerenderTabHelper
void SetURLLoaderFactoryForTesting( void SetURLLoaderFactoryForTesting(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
size_t prefetched_responses_size_for_testing() const { size_t prefetched_responses_size_for_testing() const {
return prefetched_responses_.size(); return page_ ? page_->prefetched_responses.size() : 0;
} }
// content::WebContentsObserver implementation. // content::WebContentsObserver implementation.
...@@ -56,6 +56,28 @@ class IsolatedPrerenderTabHelper ...@@ -56,6 +56,28 @@ class IsolatedPrerenderTabHelper
explicit IsolatedPrerenderTabHelper(content::WebContents* web_contents); explicit IsolatedPrerenderTabHelper(content::WebContents* web_contents);
friend class content::WebContentsUserData<IsolatedPrerenderTabHelper>; friend class content::WebContentsUserData<IsolatedPrerenderTabHelper>;
// Owns all per-pageload state in the tab helper so that new navigations only
// need to reset an instance of this class to clean up previous state.
class CurrentPageLoad {
public:
CurrentPageLoad();
~CurrentPageLoad();
// The url loader that does all the prefetches. Set only when active.
std::unique_ptr<network::SimpleURLLoader> url_loader;
// An ordered list of the URLs to prefetch.
std::vector<GURL> urls_to_prefetch;
// The number of prefetches that have been attempted on this page.
size_t num_prefetches_attempted = 0;
// All prefetched responses by URL. This is cleared every time a mainframe
// navigation commits.
std::map<GURL, std::unique_ptr<PrefetchedMainframeResponseContainer>>
prefetched_responses;
};
// A helper method to make it easier to tell when prefetching is already // A helper method to make it easier to tell when prefetching is already
// active. // active.
bool PrefetchingActive() const; bool PrefetchingActive() const;
...@@ -94,21 +116,8 @@ class IsolatedPrerenderTabHelper ...@@ -94,21 +116,8 @@ class IsolatedPrerenderTabHelper
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
// TODO(robertogden): Consider encapsulating the per-page-load members below // Owns all members which need to be reset on a new page load.
// into a separate object. std::unique_ptr<CurrentPageLoad> page_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
// An ordered list of the URLs to prefetch.
std::vector<GURL> urls_to_prefetch_;
// The number of prefetches that have been attempted on this page.
size_t num_prefetches_attempted_ = 0;
// All prefetched responses by URL. This is cleared every time a mainframe
// navigation commits.
std::map<GURL, std::unique_ptr<PrefetchedMainframeResponseContainer>>
prefetched_responses_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
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