Commit 2533bff6 authored by ananta's avatar ananta Committed by Commit Bot

Add support for subresource request loads in AppCache for the network service.

This patch builds on the earlier patch where we passed the URLLoaderFactory for AppCache
to the renderer process. The renderer invokes CreateLoaderAndStart which comes to the AppCache
factory. We then instantiate the AppCacheRequestHandler instance here and call into it to handle
the request. The handler creates the AppCacheURLLoaderJob and passes itself to the job. The job controls
the lifetime of the handler.

The AppCacheSubresourceURLFactory class is passed the precreated AppCache host during init. We save
maintain this as a weak reference in the class to protect against the case where the host dies while we are
processing the call from the renderer. Added support to get a weak pointer in the AppCacheHost class.
The AppCacheRequestHandler saves away the host as a weak reference during InitializeForNavigationNetworkService()
and passes to the factory in MaybeCreateSubresourceFactory()

The other changes are to pass the information from CreateLoaderAndStart() to the AppCacheRequestHandler class
and from there to the job. A bug was fixed in the AppCacheURLLoaderJob where we weren't terminating the write correctly
causing the renderer to not consider the load as complete.

With this change normal subresource loads will work. Fallback support is not added yet and will happen in a followup.

BUG=715632
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_site_isolation

Review-Url: https://codereview.chromium.org/2956373002
Cr-Commit-Position: refs/heads/master@{#485834}
parent 2a2713ac
...@@ -44,21 +44,26 @@ void FillCacheInfo(const AppCache* cache, ...@@ -44,21 +44,26 @@ void FillCacheInfo(const AppCache* cache,
} // Anonymous namespace } // Anonymous namespace
AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend, AppCacheHost::AppCacheHost(int host_id,
AppCacheFrontend* frontend,
AppCacheServiceImpl* service) AppCacheServiceImpl* service)
: host_id_(host_id), : host_id_(host_id),
spawning_host_id_(kAppCacheNoHostId), spawning_process_id_(0), spawning_host_id_(kAppCacheNoHostId),
parent_host_id_(kAppCacheNoHostId), parent_process_id_(0), spawning_process_id_(0),
parent_host_id_(kAppCacheNoHostId),
parent_process_id_(0),
pending_main_resource_cache_id_(kAppCacheNoCacheId), pending_main_resource_cache_id_(kAppCacheNoCacheId),
pending_selected_cache_id_(kAppCacheNoCacheId), pending_selected_cache_id_(kAppCacheNoCacheId),
was_select_cache_called_(false), was_select_cache_called_(false),
is_cache_selection_enabled_(true), is_cache_selection_enabled_(true),
frontend_(frontend), service_(service), frontend_(frontend),
service_(service),
storage_(service->storage()), storage_(service->storage()),
pending_callback_param_(NULL), pending_callback_param_(NULL),
main_resource_was_namespace_entry_(false), main_resource_was_namespace_entry_(false),
main_resource_blocked_(false), main_resource_blocked_(false),
associated_cache_info_pending_(false) { associated_cache_info_pending_(false),
weak_factory_(this) {
service_->AddObserver(this); service_->AddObserver(this);
} }
...@@ -543,6 +548,10 @@ void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) { ...@@ -543,6 +548,10 @@ void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) {
frontend_ = frontend; frontend_ = frontend;
} }
base::WeakPtr<AppCacheHost> AppCacheHost::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void AppCacheHost::AssociateNoCache(const GURL& manifest_url) { void AppCacheHost::AssociateNoCache(const GURL& manifest_url) {
// manifest url can be empty. // manifest url can be empty.
AssociateCacheHelper(NULL, manifest_url); AssociateCacheHelper(NULL, manifest_url);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "content/browser/appcache/appcache_group.h" #include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_service_impl.h" #include "content/browser/appcache/appcache_service_impl.h"
...@@ -194,6 +195,9 @@ class CONTENT_EXPORT AppCacheHost ...@@ -194,6 +195,9 @@ class CONTENT_EXPORT AppCacheHost
void PrepareForTransfer(); void PrepareForTransfer();
void CompleteTransfer(int host_id, AppCacheFrontend* frontend); void CompleteTransfer(int host_id, AppCacheFrontend* frontend);
// Returns a weak pointer reference to the host.
base::WeakPtr<AppCacheHost> GetWeakPtr();
private: private:
friend class content::AppCacheHostTest; friend class content::AppCacheHostTest;
friend class content::AppCacheStorageImplTest; friend class content::AppCacheStorageImplTest;
...@@ -353,6 +357,8 @@ class CONTENT_EXPORT AppCacheHost ...@@ -353,6 +357,8 @@ class CONTENT_EXPORT AppCacheHost
FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheTwice); FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheTwice);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, CleanupUnusedCache); FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, CleanupUnusedCache);
base::WeakPtrFactory<AppCacheHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheHost); DISALLOW_COPY_AND_ASSIGN(AppCacheHost);
}; };
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h"
#include "content/browser/appcache/appcache.h" #include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h" #include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_host.h" #include "content/browser/appcache/appcache_host.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "content/browser/appcache/appcache_url_loader_request.h" #include "content/browser/appcache/appcache_url_loader_request.h"
#include "content/browser/appcache/appcache_url_request_job.h" #include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/service_worker/service_worker_request_handler.h" #include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/public/common/content_features.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h" #include "net/url_request/url_request_job.h"
...@@ -101,7 +103,7 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadResource( ...@@ -101,7 +103,7 @@ AppCacheJob* AppCacheRequestHandler::MaybeLoadResource(
// If its been setup to deliver a network response, we can just delete // If its been setup to deliver a network response, we can just delete
// it now and return NULL instead to achieve that since it couldn't // it now and return NULL instead to achieve that since it couldn't
// have been started yet. // have been started yet.
if (job && job->IsDeliveringNetworkResponse()) { if (job && job->IsDeliveringNetworkResponse() && !job->AsURLLoaderJob()) {
DCHECK(!job->IsStarted()); DCHECK(!job->IsStarted());
job.reset(); job.reset();
} }
...@@ -238,10 +240,16 @@ AppCacheRequestHandler::InitializeForNavigationNetworkService( ...@@ -238,10 +240,16 @@ AppCacheRequestHandler::InitializeForNavigationNetworkService(
appcache_handle_core->host()->CreateRequestHandler( appcache_handle_core->host()->CreateRequestHandler(
AppCacheURLLoaderRequest::Create(request), request.resource_type, AppCacheURLLoaderRequest::Create(request), request.resource_type,
request.should_reset_appcache); request.should_reset_appcache);
handler->set_network_url_loader_factory_getter(url_loader_factory_getter); handler->network_url_loader_factory_getter_ = url_loader_factory_getter;
handler->appcache_host_ = appcache_handle_core->host()->GetWeakPtr();
return handler; return handler;
} }
void AppCacheRequestHandler::SetSubresourceRequestLoadInfo(
std::unique_ptr<SubresourceLoadInfo> subresource_load_info) {
subresource_load_info_ = std::move(subresource_load_info);
}
void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) { void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) {
storage()->CancelDelegateCallbacks(this); storage()->CancelDelegateCallbacks(this);
host_ = NULL; // no need to RemoveObserver, the host is being deleted host_ = NULL; // no need to RemoveObserver, the host is being deleted
...@@ -322,6 +330,15 @@ std::unique_ptr<AppCacheJob> AppCacheRequestHandler::CreateJob( ...@@ -322,6 +330,15 @@ std::unique_ptr<AppCacheJob> AppCacheRequestHandler::CreateJob(
base::Bind(&AppCacheRequestHandler::OnPrepareToRestart, base::Bind(&AppCacheRequestHandler::OnPrepareToRestart,
base::Unretained(this))); base::Unretained(this)));
job_ = job->GetWeakPtr(); job_ = job->GetWeakPtr();
if (!is_main_resource() &&
base::FeatureList::IsEnabled(features::kNetworkService)) {
AppCacheURLLoaderJob* loader_job = job_->AsURLLoaderJob();
loader_job->SetSubresourceLoadInfo(
std::move(subresource_load_info_),
network_url_loader_factory_getter_.get());
}
return job; return job;
} }
...@@ -543,14 +560,19 @@ void AppCacheRequestHandler::MaybeCreateLoader( ...@@ -543,14 +560,19 @@ void AppCacheRequestHandler::MaybeCreateLoader(
std::move(callback).Run(StartLoaderCallback()); std::move(callback).Run(StartLoaderCallback());
return; return;
} }
navigation_request_job_->AsURLLoaderJob()->set_loader_callback( navigation_request_job_->AsURLLoaderJob()->set_main_resource_loader_callback(
std::move(callback)); std::move(callback));
} }
mojom::URLLoaderFactoryPtr mojom::URLLoaderFactoryPtr
AppCacheRequestHandler::MaybeCreateSubresourceFactory() { AppCacheRequestHandler::MaybeCreateSubresourceFactory() {
return AppCacheSubresourceURLFactory::CreateURLLoaderFactory( mojom::URLLoaderFactoryPtr factory_ptr = nullptr;
network_url_loader_factory_getter_.get());
// The factory is destroyed when the renderer drops the connection.
AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
network_url_loader_factory_getter_.get(), appcache_host_, &factory_ptr);
return factory_ptr;
} }
} // namespace content } // namespace content
...@@ -32,7 +32,8 @@ class AppCacheNavigationHandleCore; ...@@ -32,7 +32,8 @@ class AppCacheNavigationHandleCore;
class AppCacheRequest; class AppCacheRequest;
class AppCacheRequestHandlerTest; class AppCacheRequestHandlerTest;
class AppCacheURLRequestJob; class AppCacheURLRequestJob;
struct ResourceRequest; class AppCacheHost;
struct SubresourceLoadInfo;
// An instance is created for each net::URLRequest. The instance survives all // An instance is created for each net::URLRequest. The instance survives all
// http transactions involved in the processing of its net::URLRequest, and is // http transactions involved in the processing of its net::URLRequest, and is
...@@ -80,6 +81,15 @@ class CONTENT_EXPORT AppCacheRequestHandler ...@@ -80,6 +81,15 @@ class CONTENT_EXPORT AppCacheRequestHandler
AppCacheNavigationHandleCore* appcache_handle_core, AppCacheNavigationHandleCore* appcache_handle_core,
URLLoaderFactoryGetter* url_loader_factory_getter); URLLoaderFactoryGetter* url_loader_factory_getter);
// The following setters only apply for the network service code.
void set_network_url_loader_factory_getter(
URLLoaderFactoryGetter* url_loader_factory_getter) {
network_url_loader_factory_getter_ = url_loader_factory_getter;
}
void SetSubresourceRequestLoadInfo(
std::unique_ptr<SubresourceLoadInfo> subresource_load_info);
private: private:
friend class AppCacheHost; friend class AppCacheHost;
...@@ -152,11 +162,6 @@ class CONTENT_EXPORT AppCacheRequestHandler ...@@ -152,11 +162,6 @@ class CONTENT_EXPORT AppCacheRequestHandler
LoaderCallback callback) override; LoaderCallback callback) override;
mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory() override; mojom::URLLoaderFactoryPtr MaybeCreateSubresourceFactory() override;
void set_network_url_loader_factory_getter(
URLLoaderFactoryGetter* url_loader_factory_getter) {
network_url_loader_factory_getter_ = url_loader_factory_getter;
}
// Data members ----------------------------------------------- // Data members -----------------------------------------------
// What host we're servicing a request for. // What host we're servicing a request for.
...@@ -217,6 +222,8 @@ class CONTENT_EXPORT AppCacheRequestHandler ...@@ -217,6 +222,8 @@ class CONTENT_EXPORT AppCacheRequestHandler
std::unique_ptr<AppCacheRequest> request_; std::unique_ptr<AppCacheRequest> request_;
// Network service related members.
// In the network service world we are queried via the URLLoaderRequestHandler // In the network service world we are queried via the URLLoaderRequestHandler
// interface to see if the navigation request can be handled via the // interface to see if the navigation request can be handled via the
// AppCache. We hold onto the AppCache job created here until the client // AppCache. We hold onto the AppCache job created here until the client
...@@ -230,6 +237,13 @@ class CONTENT_EXPORT AppCacheRequestHandler ...@@ -230,6 +237,13 @@ class CONTENT_EXPORT AppCacheRequestHandler
friend class content::AppCacheRequestHandlerTest; friend class content::AppCacheRequestHandlerTest;
// Subresource load information.
std::unique_ptr<SubresourceLoadInfo> subresource_load_info_;
// The AppCache host instance. We pass this to the
// AppCacheSubresourceURLFactory instance on creation.
base::WeakPtr<AppCacheHost> appcache_host_;
DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler); DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler);
}; };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_request_handler.h" #include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_url_loader_job.h" #include "content/browser/appcache/appcache_url_loader_job.h"
#include "content/browser/appcache/appcache_url_loader_request.h" #include "content/browser/appcache/appcache_url_loader_request.h"
...@@ -23,9 +24,11 @@ namespace content { ...@@ -23,9 +24,11 @@ namespace content {
// Implements the URLLoaderFactory mojom for AppCache requests. // Implements the URLLoaderFactory mojom for AppCache requests.
AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory( AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory(
mojom::URLLoaderFactoryRequest request, mojom::URLLoaderFactoryRequest request,
URLLoaderFactoryGetter* default_url_loader_factory_getter) URLLoaderFactoryGetter* default_url_loader_factory_getter,
base::WeakPtr<AppCacheHost> host)
: binding_(this, std::move(request)), : binding_(this, std::move(request)),
default_url_loader_factory_getter_(default_url_loader_factory_getter) { default_url_loader_factory_getter_(default_url_loader_factory_getter),
appcache_host_(host) {
binding_.set_connection_error_handler( binding_.set_connection_error_handler(
base::Bind(&AppCacheSubresourceURLFactory::OnConnectionError, base::Bind(&AppCacheSubresourceURLFactory::OnConnectionError,
base::Unretained(this))); base::Unretained(this)));
...@@ -34,17 +37,17 @@ AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory( ...@@ -34,17 +37,17 @@ AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory(
AppCacheSubresourceURLFactory::~AppCacheSubresourceURLFactory() {} AppCacheSubresourceURLFactory::~AppCacheSubresourceURLFactory() {}
// static // static
mojom::URLLoaderFactoryPtr AppCacheSubresourceURLFactory*
AppCacheSubresourceURLFactory::CreateURLLoaderFactory( AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
URLLoaderFactoryGetter* default_url_loader_factory_getter) { URLLoaderFactoryGetter* default_url_loader_factory_getter,
mojom::URLLoaderFactoryPtr loader_factory; base::WeakPtr<AppCacheHost> host,
mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(&loader_factory); mojom::URLLoaderFactoryPtr* loader_factory) {
mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(loader_factory);
// This instance will get deleted when the client drops the connection. // This instance will get deleted when the client drops the connection.
// Please see OnConnectionError() for details. // Please see OnConnectionError() for details.
new AppCacheSubresourceURLFactory(std::move(request), return new AppCacheSubresourceURLFactory(
default_url_loader_factory_getter); std::move(request), default_url_loader_factory_getter, host);
return loader_factory;
} }
void AppCacheSubresourceURLFactory::CreateLoaderAndStart( void AppCacheSubresourceURLFactory::CreateLoaderAndStart(
...@@ -57,11 +60,42 @@ void AppCacheSubresourceURLFactory::CreateLoaderAndStart( ...@@ -57,11 +60,42 @@ void AppCacheSubresourceURLFactory::CreateLoaderAndStart(
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
DLOG(WARNING) << "Received request for loading : " << request.url.spec(); DLOG(WARNING) << "Received request for loading : " << request.url.spec();
default_url_loader_factory_getter_->GetNetworkFactory()
->get() // If the host is invalid, it means that the renderer has probably died.
->CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest(), routing_id, // (Frame has navigated elsewhere?)
request_id, options, request, std::move(client), if (!appcache_host_.get())
traffic_annotation); return;
std::unique_ptr<AppCacheRequestHandler> handler =
appcache_host_->CreateRequestHandler(
AppCacheURLLoaderRequest::Create(request), request.resource_type,
request.should_reset_appcache);
if (!handler) {
ResourceRequestCompletionStatus request_result;
request_result.error_code = net::ERR_FAILED;
client->OnComplete(request_result);
return;
}
handler->set_network_url_loader_factory_getter(
default_url_loader_factory_getter_.get());
std::unique_ptr<SubresourceLoadInfo> load_info(new SubresourceLoadInfo());
load_info->url_loader_request = std::move(url_loader_request);
load_info->routing_id = routing_id;
load_info->request_id = request_id;
load_info->options = options;
load_info->request = request;
load_info->client = std::move(client);
load_info->traffic_annotation = traffic_annotation;
handler->SetSubresourceRequestLoadInfo(std::move(load_info));
AppCacheJob* job = handler->MaybeLoadResource(nullptr);
if (job) {
// The handler is owned by the job.
job->AsURLLoaderJob()->set_request_handler(std::move(handler));
}
} }
void AppCacheSubresourceURLFactory::SyncLoad(int32_t routing_id, void AppCacheSubresourceURLFactory::SyncLoad(int32_t routing_id,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_APPCACHE_APPCACHE_SUBRESOURCE_URL_FACTORY_H_ #define CONTENT_BROWSER_APPCACHE_APPCACHE_SUBRESOURCE_URL_FACTORY_H_
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/public/common/url_loader_factory.mojom.h" #include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation.h"
...@@ -13,6 +14,7 @@ ...@@ -13,6 +14,7 @@
namespace content { namespace content {
class AppCacheHost;
class AppCacheJob; class AppCacheJob;
class AppCacheServiceImpl; class AppCacheServiceImpl;
class URLLoaderFactoryGetter; class URLLoaderFactoryGetter;
...@@ -25,10 +27,15 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory { ...@@ -25,10 +27,15 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory {
// Factory function to create an instance of the factory. // Factory function to create an instance of the factory.
// 1. The |factory_getter| parameter is used to query the network service // 1. The |factory_getter| parameter is used to query the network service
// to pass network requests to. // to pass network requests to.
// Returns a URLLoaderFactoryPtr instance which controls the lifetime of the // 2. The |host| parameter contains the appcache host instance. This is used
// factory. // to create the AppCacheRequestHandler instances for handling subresource
static mojom::URLLoaderFactoryPtr CreateURLLoaderFactory( // requests.
URLLoaderFactoryGetter* factory_getter); // Returns the AppCacheSubresourceURLFactory instance. The URLLoaderFactoryPtr
// is returned in the |loader_factory| parameter.
static AppCacheSubresourceURLFactory* CreateURLLoaderFactory(
URLLoaderFactoryGetter* factory_getter,
base::WeakPtr<AppCacheHost> host,
mojom::URLLoaderFactoryPtr* loader_factory);
// mojom::URLLoaderFactory implementation. // mojom::URLLoaderFactory implementation.
void CreateLoaderAndStart( void CreateLoaderAndStart(
...@@ -47,7 +54,8 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory { ...@@ -47,7 +54,8 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory {
private: private:
AppCacheSubresourceURLFactory(mojom::URLLoaderFactoryRequest request, AppCacheSubresourceURLFactory(mojom::URLLoaderFactoryRequest request,
URLLoaderFactoryGetter* factory_getter); URLLoaderFactoryGetter* factory_getter,
base::WeakPtr<AppCacheHost> host);
void OnConnectionError(); void OnConnectionError();
...@@ -58,6 +66,8 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory { ...@@ -58,6 +66,8 @@ class AppCacheSubresourceURLFactory : public mojom::URLLoaderFactory {
// the network service. // the network service.
scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
base::WeakPtr<AppCacheHost> appcache_host_;
DISALLOW_COPY_AND_ASSIGN(AppCacheSubresourceURLFactory); DISALLOW_COPY_AND_ASSIGN(AppCacheSubresourceURLFactory);
}; };
......
...@@ -6,12 +6,19 @@ ...@@ -6,12 +6,19 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "content/browser/appcache/appcache_histograms.h" #include "content/browser/appcache/appcache_histograms.h"
#include "content/browser/appcache/appcache_subresource_url_factory.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/net_adapters.h" #include "content/common/net_adapters.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
namespace content { namespace content {
SubresourceLoadInfo::SubresourceLoadInfo()
: routing_id(-1), request_id(-1), options(0) {}
SubresourceLoadInfo::~SubresourceLoadInfo() {}
AppCacheURLLoaderJob::~AppCacheURLLoaderJob() { AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {
if (storage_.get()) if (storage_.get())
storage_->CancelDelegateCallbacks(this); storage_->CancelDelegateCallbacks(this);
...@@ -34,6 +41,9 @@ void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, ...@@ -34,6 +41,9 @@ void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
delivery_type_ = APPCACHED_DELIVERY; delivery_type_ = APPCACHED_DELIVERY;
load_timing_info_.request_start_time = base::Time::Now();
load_timing_info_.request_start = base::TimeTicks::Now();
AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() - AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() -
start_time_tick_); start_time_tick_);
...@@ -59,11 +69,22 @@ void AppCacheURLLoaderJob::DeliverNetworkResponse() { ...@@ -59,11 +69,22 @@ void AppCacheURLLoaderJob::DeliverNetworkResponse() {
AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() - AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
start_time_tick_); start_time_tick_);
DCHECK(!loader_callback_.is_null()); if (IsResourceTypeFrame(request_.resource_type)) {
// In network service land, if we are processing a navigation request, we DCHECK(!main_resource_loader_callback_.is_null());
// need to inform the loader callback that we are not going to handle this // In network service land, if we are processing a navigation request, we
// request. The loader callback is valid only for navigation requests. // need to inform the loader callback that we are not going to handle this
std::move(loader_callback_).Run(StartLoaderCallback()); // request. The loader callback is valid only for navigation requests.
std::move(main_resource_loader_callback_).Run(StartLoaderCallback());
} else {
default_url_loader_factory_getter_->GetNetworkFactory()
->get()
->CreateLoaderAndStart(
mojo::MakeRequest(&network_loader_request_),
subresource_load_info_->routing_id,
subresource_load_info_->request_id, subresource_load_info_->options,
subresource_load_info_->request, std::move(client_info_),
subresource_load_info_->traffic_annotation);
}
} }
void AppCacheURLLoaderJob::DeliverErrorResponse() { void AppCacheURLLoaderJob::DeliverErrorResponse() {
...@@ -99,12 +120,28 @@ AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() { ...@@ -99,12 +120,28 @@ AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
} }
void AppCacheURLLoaderJob::FollowRedirect() { void AppCacheURLLoaderJob::FollowRedirect() {
DCHECK(false); if (network_loader_request_)
network_loader_request_->FollowRedirect();
} }
void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority, void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) { int32_t intra_priority_value) {
NOTREACHED() << "We don't support SetPriority()"; if (network_loader_request_)
network_loader_request_->SetPriority(priority, intra_priority_value);
}
void AppCacheURLLoaderJob::SetSubresourceLoadInfo(
std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
URLLoaderFactoryGetter* default_url_loader) {
subresource_load_info_ = std::move(subresource_load_info);
associated_binding_.reset(new mojo::AssociatedBinding<mojom::URLLoader>(
this, std::move(subresource_load_info_->url_loader_request)));
associated_binding_->set_connection_error_handler(base::Bind(
&AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
client_info_ = std::move(subresource_load_info_->client);
default_url_loader_factory_getter_ = default_url_loader;
} }
void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request, void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
...@@ -151,9 +188,11 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded( ...@@ -151,9 +188,11 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
if (is_range_request()) if (is_range_request())
SetupRangeResponse(); SetupRangeResponse();
DCHECK(!loader_callback_.is_null()); if (IsResourceTypeFrame(request_.resource_type)) {
std::move(loader_callback_) DCHECK(!main_resource_loader_callback_.is_null());
.Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this))); std::move(main_resource_loader_callback_)
.Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this)));
}
response_body_stream_ = std::move(data_pipe_.producer_handle); response_body_stream_ = std::move(data_pipe_.producer_handle);
...@@ -185,6 +224,12 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded( ...@@ -185,6 +224,12 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
void AppCacheURLLoaderJob::OnReadComplete(int result) { void AppCacheURLLoaderJob::OnReadComplete(int result) {
DLOG(WARNING) << "AppCache read completed with result: " << result; DLOG(WARNING) << "AppCache read completed with result: " << result;
if (result <= 0) {
writable_handle_watcher_.Cancel();
pending_write_->Complete(0);
pending_write_ = nullptr;
}
bool is_main_resource = IsResourceTypeFrame(request_.resource_type); bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
if (result == 0) { if (result == 0) {
...@@ -216,7 +261,6 @@ void AppCacheURLLoaderJob::OnConnectionError() { ...@@ -216,7 +261,6 @@ void AppCacheURLLoaderJob::OnConnectionError() {
void AppCacheURLLoaderJob::SendResponseInfo() { void AppCacheURLLoaderJob::SendResponseInfo() {
DCHECK(client_info_); DCHECK(client_info_);
// If this is null it means the response information was sent to the client. // If this is null it means the response information was sent to the client.
if (!data_pipe_.consumer_handle.is_valid()) if (!data_pipe_.consumer_handle.is_valid())
return; return;
...@@ -227,18 +271,28 @@ void AppCacheURLLoaderJob::SendResponseInfo() { ...@@ -227,18 +271,28 @@ void AppCacheURLLoaderJob::SendResponseInfo() {
ResourceResponseHead response_head; ResourceResponseHead response_head;
response_head.headers = http_info->headers; response_head.headers = http_info->headers;
response_head.appcache_id = cache_id_;
response_head.appcache_manifest_url = manifest_url_;
// TODO(ananta)
// Copy more fields.
http_info->headers->GetMimeType(&response_head.mime_type); http_info->headers->GetMimeType(&response_head.mime_type);
http_info->headers->GetCharset(&response_head.charset); http_info->headers->GetCharset(&response_head.charset);
// TODO(ananta)
// Verify if the times sent here are correct.
response_head.request_time = http_info->request_time; response_head.request_time = http_info->request_time;
response_head.response_time = http_info->response_time; response_head.response_time = http_info->response_time;
response_head.content_length = response_head.content_length =
is_range_request() ? range_response_info_->headers->GetContentLength() is_range_request() ? range_response_info_->headers->GetContentLength()
: info_->response_data_size(); : info_->response_data_size();
response_head.connection_info = http_info->connection_info;
response_head.socket_address = http_info->socket_address;
response_head.was_fetched_via_spdy = http_info->was_fetched_via_spdy;
response_head.was_alpn_negotiated = http_info->was_alpn_negotiated;
response_head.alpn_negotiated_protocol = http_info->alpn_negotiated_protocol;
response_head.load_timing = load_timing_info_;
client_info_->OnReceiveResponse(response_head, http_info->ssl_info, client_info_->OnReceiveResponse(response_head, http_info->ssl_info,
mojom::DownloadedTempFilePtr()); mojom::DownloadedTempFilePtr());
...@@ -289,10 +343,26 @@ void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) { ...@@ -289,10 +343,26 @@ void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
void AppCacheURLLoaderJob::NotifyCompleted(int error_code) { void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
if (storage_.get()) if (storage_.get())
storage_->CancelDelegateCallbacks(this); storage_->CancelDelegateCallbacks(this);
// TODO(ananta)
// Fill other details in the ResourceRequestCompletionStatus structure. const net::HttpResponseInfo* http_info = is_range_request()
? range_response_info_.get()
: info_->http_response_info();
ResourceRequestCompletionStatus request_complete_data; ResourceRequestCompletionStatus request_complete_data;
request_complete_data.error_code = error_code; request_complete_data.error_code = error_code;
// TODO(ananta)
// Fill other details in the ResourceRequestCompletionStatus structure in
// case of an error.
if (!request_complete_data.error_code) {
request_complete_data.exists_in_cache = http_info->was_cached;
request_complete_data.completion_time = base::TimeTicks::Now();
request_complete_data.encoded_body_length =
is_range_request() ? range_response_info_->headers->GetContentLength()
: info_->response_data_size();
request_complete_data.decoded_body_length =
request_complete_data.encoded_body_length;
}
client_info_->OnComplete(request_complete_data); client_info_->OnComplete(request_complete_data);
} }
......
...@@ -12,12 +12,14 @@ ...@@ -12,12 +12,14 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "content/browser/appcache/appcache_entry.h" #include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_job.h" #include "content/browser/appcache/appcache_job.h"
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_response.h" #include "content/browser/appcache/appcache_response.h"
#include "content/browser/appcache/appcache_storage.h" #include "content/browser/appcache/appcache_storage.h"
#include "content/browser/loader/url_loader_request_handler.h" #include "content/browser/loader/url_loader_request_handler.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/common/resource_request.h" #include "content/public/common/resource_request.h"
#include "content/public/common/url_loader.mojom.h" #include "content/public/common/url_loader.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/data_pipe.h"
...@@ -25,6 +27,23 @@ namespace content { ...@@ -25,6 +27,23 @@ namespace content {
class AppCacheRequest; class AppCacheRequest;
class NetToMojoPendingBuffer; class NetToMojoPendingBuffer;
class URLLoaderFactoryGetter;
struct SubresourceLoadInfo;
// Holds information about the subresource load request like the routing id,
// request id, the client pointer, etc.
struct SubresourceLoadInfo {
SubresourceLoadInfo();
~SubresourceLoadInfo();
mojom::URLLoaderAssociatedRequest url_loader_request;
int32_t routing_id;
int32_t request_id;
uint32_t options;
ResourceRequest request;
mojom::URLLoaderClientPtr client;
net::MutableNetworkTrafficAnnotationTag traffic_annotation;
};
// AppCacheJob wrapper for a mojom::URLLoader implementation which returns // AppCacheJob wrapper for a mojom::URLLoader implementation which returns
// responses stored in the AppCache. // responses stored in the AppCache.
...@@ -54,8 +73,23 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob, ...@@ -54,8 +73,23 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
void SetPriority(net::RequestPriority priority, void SetPriority(net::RequestPriority priority,
int32_t intra_priority_value) override; int32_t intra_priority_value) override;
void set_loader_callback(LoaderCallback callback) { void set_main_resource_loader_callback(LoaderCallback callback) {
loader_callback_ = std::move(callback); main_resource_loader_callback_ = std::move(callback);
}
// Subresource request load information is passed in the
// |subresource_load_info| parameter. This includes the request id, the
// client pointer, etc.
// |default_url_loader| is used to retrieve the network loader for requests
// intended to be sent to the network.
void SetSubresourceLoadInfo(
std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
URLLoaderFactoryGetter* default_url_loader);
// Ownership of the |handler| is transferred to us via this call. This is
// only for subresource requests.
void set_request_handler(std::unique_ptr<AppCacheRequestHandler> handler) {
sub_resource_handler_ = std::move(handler);
} }
protected: protected:
...@@ -123,8 +157,29 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob, ...@@ -123,8 +157,29 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
mojo::SimpleWatcher writable_handle_watcher_; mojo::SimpleWatcher writable_handle_watcher_;
// The Callback to be invoked in the network service land to indicate if // The Callback to be invoked in the network service land to indicate if
// the request can be serviced via the AppCache. // the main resource request can be serviced via the AppCache.
LoaderCallback loader_callback_; LoaderCallback main_resource_loader_callback_;
// We own the AppCacheRequestHandler instance for subresource requests.
std::unique_ptr<AppCacheRequestHandler> sub_resource_handler_;
scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
// Holds subresource url loader information.
std::unique_ptr<SubresourceLoadInfo> subresource_load_info_;
// Timing information for the most recent request. Its start times are
// populated in DeliverAppCachedResponse().
net::LoadTimingInfo load_timing_info_;
// Used for subresource requests which go to the network.
mojom::URLLoaderAssociatedPtr network_loader_request_;
// Binds the subresource URLLoaderClient with us. We can use the regular
// binding_ member above when we remove the need for the associated requests
// issue with URLLoaderFactory.
std::unique_ptr<mojo::AssociatedBinding<mojom::URLLoader>>
associated_binding_;
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderJob); DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderJob);
}; };
......
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