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

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: rebase to tip 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 71fa7f16805d92a7c452397a19c87890c9894ce1..c7c432fe76459611ddf22558873150864a2df914 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),
+ response_loader_binding_(this) {}
~URLLoaderRequestController() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -177,6 +178,7 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
// This could be called multiple times.
void Restart() {
handler_index_ = 0;
+ received_response_ = false;
MaybeStartLoader(StartLoaderCallback());
}
@@ -213,6 +215,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,
@@ -227,6 +230,8 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(url_loader_);
+ DCHECK(!response_url_loader_);
+
url_loader_->FollowRedirect();
}
@@ -242,6 +247,13 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
const ResourceResponseHead& head,
const base::Optional<net::SSLInfo>& ssl_info,
mojom::DownloadedTempFilePtr downloaded_file) override {
+ received_response_ = true;
+ // If the default loader (network) was used to handle the URL load request
+ // we need to see if the handlers want to potentially create a new loader
+ // for the response. e.g. AppCache.
+ if (MaybeCreateLoaderForResponse(head))
+ return;
+
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse,
@@ -277,12 +289,51 @@ class NavigationURLLoaderNetworkService::URLLoaderRequestController
void OnComplete(
const ResourceRequestCompletionStatus& completion_status) override {
+ if (completion_status.error_code != net::OK && !received_response_) {
+ // If the default loader (network) was used to handle the URL load
+ // request we need to see if the handlers want to potentially create a
+ // new loader for the response. e.g. AppCache.
+ if (MaybeCreateLoaderForResponse(ResourceResponseHead()))
+ return;
+ }
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_,
completion_status));
}
+ // Returns true if a handler wants to handle the response, i.e. return a
+ // different response. For e.g. AppCache may have fallback content to be
+ // returned for a TLD.
+ bool MaybeCreateLoaderForResponse(const ResourceResponseHead& response) {
+ if (!default_loader_used_)
+ return false;
+
+ // URLLoaderClient request pointer for response loaders, i.e loaders created
+ // for handing responses received from the network URLLoader.
+ mojom::URLLoaderClientRequest response_client_request;
+
+ for (size_t index = 0; index < handlers_.size(); ++index) {
+ if (handlers_[index]->MaybeCreateLoaderForResponse(
+ response, &response_url_loader_, &response_client_request)) {
+ OnResponseHandlerFound(std::move(response_client_request));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Called if we find a handler who delivers different content for the URL.
+ void OnResponseHandlerFound(
+ mojom::URLLoaderClientRequest response_client_request) {
+ response_loader_binding_.Bind(std::move(response_client_request));
+ // We reset this flag as we expect a new response from the handler.
+ default_loader_used_ = false;
+ // Disconnect from the network loader to stop receiving further data
+ // or notifications for the URL.
+ url_loader_->DisconnectClient();
+ }
+
std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_;
size_t handler_index_ = 0;
@@ -305,6 +356,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;
+
+ // URLLoaderClient binding for loaders created for responses received from the
+ // network loader.
+ mojo::Binding<mojom::URLLoaderClient> response_loader_binding_;
+
+ // URLLoader instance for response loaders, i.e loaders created for handing
+ // responses received from the network URLLoader.
+ mojom::URLLoaderPtr response_url_loader_;
+
+ // Set to true if we receive a valid response from a URLLoader, i.e.
+ // URLLoaderClient::OnReceivedResponse() is called.
+ bool received_response_ = false;
+
DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
};
« no previous file with comments | « content/browser/appcache/appcache_url_loader_job.cc ('k') | content/browser/loader/url_loader_request_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698