Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1111)

Unified Diff: content/browser/loader/navigation_url_loader_network_service.cc

Issue 2982363002: Add support for fallback content for the frame. This includes main and subframes. (Closed)
Patch Set: Address review comments. Add the fallback function as a parameter to LoaderCallback Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/loader/navigation_url_loader_network_service.cc
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index b821082ae37eb74b98d72706a042a7e8d621aaab..25eaee403a0ae9a50c064c350f9dec3f595375e1 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -105,7 +105,8 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
: resource_request_(std::move(resource_request)),
resource_context_(resource_context),
default_url_loader_factory_getter_(default_url_loader_factory_getter),
- owner_(owner) {}
+ owner_(owner),
+ fallback_response_binding_(this) {}
~URLLoaderRequestController() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -177,11 +178,13 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
// This could be called multiple times.
void Restart() {
handler_index_ = 0;
- MaybeStartLoader(StartLoaderCallback());
+ MaybeStartLoader(StartLoaderCallback(), ResponseFallback());
}
- void MaybeStartLoader(StartLoaderCallback start_loader_callback) {
+ void MaybeStartLoader(StartLoaderCallback start_loader_callback,
+ ResponseFallback fallback) {
if (start_loader_callback) {
+ DCHECK(!fallback);
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
std::move(start_loader_callback),
GetContentClient()->browser()->CreateURLLoaderThrottles(
@@ -197,6 +200,11 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
subresource_loader_factory.PassInterface();
}
return;
+ } else {
+ // We only support one fallback handler at any given point. AppCache is
+ // the only handler which supports fallback responses.
+ DCHECK(!fallback_handler_);
+ fallback_handler_ = std::move(fallback);
}
if (handler_index_ < handlers_.size()) {
@@ -213,6 +221,7 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
factory = default_url_loader_factory_getter_->GetBlobFactory()->get();
} else {
factory = default_url_loader_factory_getter_->GetNetworkFactory()->get();
+ default_loader_used_ = true;
}
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
factory,
@@ -242,6 +251,12 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
const ResourceResponseHead& head,
const base::Optional<net::SSLInfo>& ssl_info,
mojom::DownloadedTempFilePtr downloaded_file) override {
+ response_ = head;
+ // If the default loader (network) was used to handle the URL load request
+ // we need to see if the handlers want to load a fallback for the response.
+ if (MaybeLoadFallbackForResponse(head))
+ return;
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse,
@@ -250,6 +265,8 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const ResourceResponseHead& head) override {
+ response_ = head;
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderNetworkService::OnReceiveRedirect,
@@ -277,12 +294,48 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
void OnComplete(
const ResourceRequestCompletionStatus& completion_status) override {
+ // If the default loader (network) was used to handle the URL load request
+ // we need to see if the handlers want to load a fallback for the response.
+ if (MaybeLoadFallbackForResponse(response_))
+ return;
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_,
completion_status));
}
+ // Returns true if a handler returns a fallback response.
+ bool MaybeLoadFallbackForResponse(const ResourceResponseHead& response) {
+ mojom::URLLoaderClientPtr fallback_client;
+ mojom::URLLoaderRequest fallback_request;
+ if (!CreateFallbackClientAndRequest(&fallback_client, &fallback_request))
+ return false;
+
+ // We reset this flag as we expect a response from the fallback handler.
+ default_loader_used_ = false;
+ // Disconnect from the network loader to stop receiving further data
+ // or notifications for the URL.
+ url_loader_->DisconnectClient();
+
+ return std::move(fallback_handler_)
+ .Run(response, std::move(fallback_client), std::move(fallback_request));
kinuko 2017/07/27 13:46:26 This fallback code works in a very specific way, w
ananta 2017/07/27 22:07:14 It seems like the method name you suggested in an
+ }
+
+ // Creates an instance of the URLLoaderClient interface which can be bound
+ // to a handler for receiving fallback responses.
+ // Returns true on success.
+ bool CreateFallbackClientAndRequest(mojom::URLLoaderClientPtr* client,
+ mojom::URLLoaderRequest* request) {
+ // Ignore if we don't have a fallback handler or if the request never went
+ // to the network loader.
+ if (!default_loader_used_ || !fallback_handler_)
+ return false;
+ fallback_response_binding_.Bind(mojo::MakeRequest(client));
+ *request = mojo::MakeRequest(&fallback_url_loader_);
+ return true;
+ }
+
std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_;
size_t handler_index_ = 0;
@@ -305,6 +358,22 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
// This is referenced only on the UI thread.
base::WeakPtr<NavigationURLLoaderNetworkService> owner_;
+ // Set to true if the default URLLoader (network service) was used for the
+ // current navigation.
+ bool default_loader_used_ = false;
+
+ // Contains a copy of the response.
+ ResourceResponseHead response_;
+
+ // URLLoaderClient binding for handling fallback responses.
+ mojo::Binding<mojom::URLLoaderClient> fallback_response_binding_;
+
+ // URLLoader instance for fallback responses.
+ mojom::URLLoaderPtr fallback_url_loader_;
+
+ // Fallback response handler.
+ ResponseFallback fallback_handler_;
+
DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
};

Powered by Google App Engine
This is Rietveld 408576698