Get main frame and subframe AppCache loads to work.
The latest iteration of this patch now has AppCache working for the main frame and
subframe. Subresource loads will be addressed in a later patchset. With this change
the w3schools.com AppCache sample here https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_html_manifest
works.
This has been integrated with kinuko's patch, i.e. we implement the URLLoaderRequestHandler interface to
validate if the request can be serviced via the AppCache.
The URLLoaderFactory for AppCache is now instantiated as needed.
Changes in this patch include the following:
1. The AppCacheRequestHandler class now implements the URLLoaderRequestHandler interface. The handler then initializes
the AppCacheURLLoader job which allows us to determine if the request would be serviced via the AppCache. If yes
we return the URLLoaderFactory for the AppCache in the callback or pass null to the callback.
2. We call the AppCacheRequestHandler::InitializeForNavigationNetworkService() function from
NavigationURLLoaderNetworkService::URLLoaderRequestController::Start() for AppCache.
3. Use the AppCacheResponseReader and AppCacheResponseInfo classes in AppCacheURLLoaderJob to read data from the AppCache.
The job invokes methods on the URLLoaderClient when it reads the response/data, etc.
The data from the AppCache is written to a mojo data pipe and passed to the client.
4. I reverted portions of the previous change to the AppCacheURLLoaderRequest class, which was to hold on to a
unique_ptr for the ResourceRequest. We now hold on to a copy of the request. The CreateLoaderAndStart() method on the factory gives us a
copy of the request.
5. Moved some of the methods like IsWaiting/IsDeliveringAppCacheResponse/IsDeliveringNetworkResponse/IsDeliveringErrorResponse/IsCacheEntryNotFound to the
AppCacheJob base class as these implementations could be shared between the URLRequest and URLLoader versions of the subclasses. I also moved the
member variables used by these methods to the base class.
6. Add WeakPtrFactory to the AppCacheStorage class and provide a getter to return a weak pointer reference to the instance.
BUG=715632
Review-Url: https://codereview.chromium.org/2902653002
Cr-Commit-Position: refs/heads/master@{#478459}
diff --git a/content/browser/appcache/appcache_job.cc b/content/browser/appcache/appcache_job.cc
index 271553f..5bd29cc 100644
--- a/content/browser/appcache/appcache_job.cc
+++ b/content/browser/appcache/appcache_job.cc
@@ -23,7 +23,8 @@
std::unique_ptr<AppCacheJob> job;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableNetworkService)) {
- job.reset(new AppCacheURLLoaderJob);
+ job.reset(
+ new AppCacheURLLoaderJob(*(request->GetResourceRequest()), storage));
} else {
job.reset(new AppCacheURLRequestJob(request->GetURLRequest(),
network_delegate, storage, host,
@@ -36,6 +37,26 @@
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
+bool AppCacheJob::IsWaiting() const {
+ return delivery_type_ == AWAITING_DELIVERY_ORDERS;
+}
+
+bool AppCacheJob::IsDeliveringAppCacheResponse() const {
+ return delivery_type_ == APPCACHED_DELIVERY;
+}
+
+bool AppCacheJob::IsDeliveringNetworkResponse() const {
+ return delivery_type_ == NETWORK_DELIVERY;
+}
+
+bool AppCacheJob::IsDeliveringErrorResponse() const {
+ return delivery_type_ == ERROR_DELIVERY;
+}
+
+bool AppCacheJob::IsCacheEntryNotFound() const {
+ return cache_entry_not_found_;
+}
+
base::WeakPtr<AppCacheJob> AppCacheJob::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -48,6 +69,9 @@
return nullptr;
}
-AppCacheJob::AppCacheJob() : weak_factory_(this) {}
+AppCacheJob::AppCacheJob()
+ : cache_entry_not_found_(false),
+ delivery_type_(AWAITING_DELIVERY_ORDERS),
+ weak_factory_(this) {}
} // namespace content
diff --git a/content/browser/appcache/appcache_job.h b/content/browser/appcache/appcache_job.h
index e43bb121..c18c772 100644
--- a/content/browser/appcache/appcache_job.h
+++ b/content/browser/appcache/appcache_job.h
@@ -35,6 +35,13 @@
// of the AppCache code.
class CONTENT_EXPORT AppCacheJob : public base::SupportsWeakPtr<AppCacheJob> {
public:
+ enum DeliveryType {
+ AWAITING_DELIVERY_ORDERS,
+ APPCACHED_DELIVERY,
+ NETWORK_DELIVERY,
+ ERROR_DELIVERY
+ };
+
// Callback that will be invoked before the request is restarted. The caller
// can use this opportunity to grab state from the job to determine how it
// should behave when the request is restarted.
@@ -63,19 +70,19 @@
virtual bool IsStarted() const = 0;
// Returns true if the job is waiting for instructions.
- virtual bool IsWaiting() const = 0;
+ virtual bool IsWaiting() const;
// Returns true if the job is delivering a response from the cache.
- virtual bool IsDeliveringAppCacheResponse() const = 0;
+ virtual bool IsDeliveringAppCacheResponse() const;
// Returns true if the job is delivering a response from the network.
- virtual bool IsDeliveringNetworkResponse() const = 0;
+ virtual bool IsDeliveringNetworkResponse() const;
// Returns true if the job is delivering an error response.
- virtual bool IsDeliveringErrorResponse() const = 0;
+ virtual bool IsDeliveringErrorResponse() const;
// Returns true if the cache entry was not found in the cache.
- virtual bool IsCacheEntryNotFound() const = 0;
+ virtual bool IsCacheEntryNotFound() const;
// Informs the job of what response it should deliver. Only one of these
// methods should be called, and only once per job. A job will sit idle and
@@ -111,6 +118,12 @@
SEQUENCE_CHECKER(sequence_checker_);
+ // Set to true if the AppCache entry is not found.
+ bool cache_entry_not_found_;
+
+ // The jobs delivery status.
+ DeliveryType delivery_type_;
+
base::WeakPtrFactory<AppCacheJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheJob);
diff --git a/content/browser/appcache/appcache_request_handler.cc b/content/browser/appcache/appcache_request_handler.cc
index 870fa7d..1e2fe1b 100644
--- a/content/browser/appcache/appcache_request_handler.cc
+++ b/content/browser/appcache/appcache_request_handler.cc
@@ -9,8 +9,13 @@
#include "base/bind.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_backend_impl.h"
+#include "content/browser/appcache/appcache_host.h"
+#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/appcache/appcache_policy.h"
#include "content/browser/appcache/appcache_request.h"
+#include "content/browser/appcache/appcache_url_loader_factory.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_request_job.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "net/url_request/url_request.h"
@@ -223,6 +228,18 @@
CompleteCrossSiteTransfer(old_process_id_, old_host_id_);
}
+// static
+std::unique_ptr<AppCacheRequestHandler>
+AppCacheRequestHandler::InitializeForNavigationNetworkService(
+ const ResourceRequest& request,
+ AppCacheNavigationHandleCore* appcache_handle_core) {
+ std::unique_ptr<AppCacheRequestHandler> handler =
+ appcache_handle_core->host()->CreateRequestHandler(
+ AppCacheURLLoaderRequest::Create(request), request.resource_type,
+ request.should_reset_appcache);
+ return handler;
+}
+
void AppCacheRequestHandler::OnDestructionImminent(AppCacheHost* host) {
storage()->CancelDelegateCallbacks(this);
host_ = NULL; // no need to RemoveObserver, the host is being deleted
@@ -316,12 +333,22 @@
// If a page falls into the scope of a ServiceWorker, any matching AppCaches
// should be ignored. This depends on the ServiceWorker handler being invoked
// prior to the AppCache handler.
- if (ServiceWorkerRequestHandler::IsControlledByServiceWorker(
+ // TODO(ananta)
+ // We need to handle this for AppCache requests initiated for the network
+ // service
+ if (request_->GetURLRequest() &&
+ ServiceWorkerRequestHandler::IsControlledByServiceWorker(
request_->GetURLRequest())) {
host_->enable_cache_selection(false);
return nullptr;
}
+ if (storage()->IsInitialized() &&
+ service_->storage()->usage_map()->find(request_->GetURL().GetOrigin()) ==
+ service_->storage()->usage_map()->end()) {
+ return nullptr;
+ }
+
host_->enable_cache_selection(true);
const AppCacheHost* spawning_host =
@@ -503,4 +530,19 @@
ContinueMaybeLoadSubResource();
}
+void AppCacheRequestHandler::MaybeCreateLoader(
+ const ResourceRequest& resource_request,
+ ResourceContext* resource_context,
+ LoaderCallback callback) {
+ // MaybeLoadMainResource will invoke navigation_request_job's methods
+ // asynchronously via AppCacheStorage::Delegate.
+ navigation_request_job_ = MaybeLoadMainResource(nullptr);
+ if (!navigation_request_job_.get()) {
+ std::move(callback).Run(StartLoaderCallback());
+ return;
+ }
+ navigation_request_job_->AsURLLoaderJob()->set_loader_callback(
+ std::move(callback));
+}
+
} // namespace content
diff --git a/content/browser/appcache/appcache_request_handler.h b/content/browser/appcache/appcache_request_handler.h
index 3b7e167..b0ed05f 100644
--- a/content/browser/appcache/appcache_request_handler.h
+++ b/content/browser/appcache/appcache_request_handler.h
@@ -16,6 +16,7 @@
#include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_host.h"
#include "content/browser/appcache/appcache_service_impl.h"
+#include "content/browser/loader/url_loader_request_handler.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
@@ -26,9 +27,11 @@
namespace content {
class AppCacheJob;
+class AppCacheNavigationHandleCore;
class AppCacheRequest;
class AppCacheRequestHandlerTest;
class AppCacheURLRequestJob;
+struct ResourceRequest;
// An instance is created for each net::URLRequest. The instance survives all
// http transactions involved in the processing of its net::URLRequest, and is
@@ -39,7 +42,8 @@
: public base::SupportsUserData::Data,
public AppCacheHost::Observer,
public AppCacheServiceImpl::Observer,
- public AppCacheStorage::Delegate {
+ public AppCacheStorage::Delegate,
+ public URLLoaderRequestHandler {
public:
~AppCacheRequestHandler() override;
@@ -69,6 +73,11 @@
type == RESOURCE_TYPE_SHARED_WORKER;
}
+ static std::unique_ptr<AppCacheRequestHandler>
+ InitializeForNavigationNetworkService(
+ const ResourceRequest& request,
+ AppCacheNavigationHandleCore* appcache_handle_core);
+
private:
friend class AppCacheHost;
@@ -135,6 +144,11 @@
// AppCacheHost::Observer override
void OnCacheSelectionComplete(AppCacheHost* host) override;
+ // URLLoaderRequestHandler override
+ void MaybeCreateLoader(const ResourceRequest& resource_request,
+ ResourceContext* resource_context,
+ LoaderCallback callback) override;
+
// Data members -----------------------------------------------
// What host we're servicing a request for.
@@ -195,6 +209,13 @@
std::unique_ptr<AppCacheRequest> request_;
+ // In the network service world we are queried via the URLLoaderRequestHandler
+ // interface to see if the navigation request can be handled via the
+ // AppCache. We hold onto the AppCache job created here until the client
+ // binds to it (Serviced via AppCache). If the request cannot be handled via
+ // the AppCache, we delete the job.
+ std::unique_ptr<AppCacheJob> navigation_request_job_;
+
friend class content::AppCacheRequestHandlerTest;
DISALLOW_COPY_AND_ASSIGN(AppCacheRequestHandler);
};
diff --git a/content/browser/appcache/appcache_storage.cc b/content/browser/appcache/appcache_storage.cc
index 0299ddc1..666acd56 100644
--- a/content/browser/appcache/appcache_storage.cc
+++ b/content/browser/appcache/appcache_storage.cc
@@ -18,9 +18,11 @@
const int64_t AppCacheStorage::kUnitializedId = -1;
AppCacheStorage::AppCacheStorage(AppCacheServiceImpl* service)
- : last_cache_id_(kUnitializedId), last_group_id_(kUnitializedId),
- last_response_id_(kUnitializedId), service_(service) {
-}
+ : last_cache_id_(kUnitializedId),
+ last_group_id_(kUnitializedId),
+ last_response_id_(kUnitializedId),
+ service_(service),
+ weak_factory_(this) {}
AppCacheStorage::~AppCacheStorage() {
DCHECK(delegate_references_.empty());
@@ -94,6 +96,10 @@
info_load->StartIfNeeded();
}
+base::WeakPtr<AppCacheStorage> AppCacheStorage::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
void AppCacheStorage::UpdateUsageMapAndNotify(const GURL& origin,
int64_t new_usage) {
DCHECK_GE(new_usage, 0);
diff --git a/content/browser/appcache/appcache_storage.h b/content/browser/appcache/appcache_storage.h
index d01de851..10a3d4c 100644
--- a/content/browser/appcache/appcache_storage.h
+++ b/content/browser/appcache/appcache_storage.h
@@ -15,6 +15,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/appcache/appcache_working_set.h"
#include "content/common/content_export.h"
#include "net/base/completion_callback.h"
@@ -194,6 +195,9 @@
virtual void DeleteResponses(const GURL& manifest_url,
const std::vector<int64_t>& response_ids) = 0;
+ // Returns true if the AppCacheStorage instance is initialized.
+ virtual bool IsInitialized() = 0;
+
// Generates unique storage ids for different object types.
int64_t NewCacheId() { return ++last_cache_id_; }
int64_t NewGroupId() { return ++last_group_id_; }
@@ -207,6 +211,9 @@
// Simple ptr back to the service object that owns us.
AppCacheServiceImpl* service() { return service_; }
+ // Returns a weak pointer reference to the AppCacheStorage instance.
+ base::WeakPtr<AppCacheStorage> GetWeakPtr();
+
protected:
friend class content::AppCacheQuotaClientTest;
friend class content::AppCacheResponseTest;
@@ -326,6 +333,10 @@
FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, DelegateReferences);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheStorageTest, UsageMap);
+ // The WeakPtrFactory below must occur last in the class definition so they
+ // get destroyed last.
+ base::WeakPtrFactory<AppCacheStorage> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(AppCacheStorage);
};
diff --git a/content/browser/appcache/appcache_storage_impl.cc b/content/browser/appcache/appcache_storage_impl.cc
index 2159d159..0307853 100644
--- a/content/browser/appcache/appcache_storage_impl.cc
+++ b/content/browser/appcache/appcache_storage_impl.cc
@@ -1779,6 +1779,10 @@
StartDeletingResponses(response_ids);
}
+bool AppCacheStorageImpl::IsInitialized() {
+ return IsInitTaskComplete();
+}
+
void AppCacheStorageImpl::DelayedStartDeletingUnusedResponses() {
// Only if we haven't already begun.
if (!did_start_deleting_responses_) {
diff --git a/content/browser/appcache/appcache_storage_impl.h b/content/browser/appcache/appcache_storage_impl.h
index 82a6f5a2..067b3e6 100644
--- a/content/browser/appcache/appcache_storage_impl.h
+++ b/content/browser/appcache/appcache_storage_impl.h
@@ -73,6 +73,7 @@
const std::vector<int64_t>& response_ids) override;
void DeleteResponses(const GURL& manifest_url,
const std::vector<int64_t>& response_ids) override;
+ bool IsInitialized() override;
private:
// The AppCacheStorageImpl class methods and datamembers may only be
diff --git a/content/browser/appcache/appcache_url_loader_factory.cc b/content/browser/appcache/appcache_url_loader_factory.cc
index 37c105a..aa2bdbeb 100644
--- a/content/browser/appcache/appcache_url_loader_factory.cc
+++ b/content/browser/appcache/appcache_url_loader_factory.cc
@@ -6,157 +6,40 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "content/browser/appcache/appcache_entry.h"
-#include "content/browser/appcache/appcache_policy.h"
-#include "content/browser/appcache/appcache_request.h"
-#include "content/browser/appcache/appcache_storage.h"
-#include "content/browser/appcache/chrome_appcache_service.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_request.h"
#include "content/browser/url_loader_factory_getter.h"
-#include "content/common/network_service.mojom.h"
#include "content/common/resource_request.h"
-#include "content/common/url_loader.mojom.h"
#include "content/common/url_loader_factory.mojom.h"
#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
-#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
namespace content {
-namespace {
-
-// Handles AppCache URL loads for the network service.
-class AppCacheURLLoader : public AppCacheStorage::Delegate,
- public mojom::URLLoader {
- public:
- AppCacheURLLoader(const ResourceRequest& request,
- mojom::URLLoaderAssociatedRequest url_loader_request,
- int32_t routing_id,
- int32_t request_id,
- mojom::URLLoaderClientPtr client_info,
- ChromeAppCacheService* appcache_service,
- URLLoaderFactoryGetter* factory_getter)
- : request_(request),
- routing_id_(routing_id),
- request_id_(request_id),
- client_info_(std::move(client_info)),
- appcache_service_(appcache_service),
- factory_getter_(factory_getter),
- binding_(this, std::move(url_loader_request)) {
- binding_.set_connection_error_handler(base::Bind(
- &AppCacheURLLoader::OnConnectionError, base::Unretained(this)));
- }
-
- ~AppCacheURLLoader() override {}
-
- void Start() {
- // If the origin does not exist in the AppCache usage map, then we can
- // safely call the network service here.
- if (appcache_service_->storage()->usage_map()->find(
- request_.url.GetOrigin()) ==
- appcache_service_->storage()->usage_map()->end()) {
- factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
- mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_,
- mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_));
- return;
- }
-
- appcache_service_->storage()->FindResponseForMainRequest(request_.url,
- GURL(), this);
- }
-
- // mojom::URLLoader implementation:
- void FollowRedirect() override { network_loader_request_->FollowRedirect(); }
-
- void SetPriority(net::RequestPriority priority,
- int32_t intra_priority_value) override {
- DCHECK(false);
- }
-
- private:
- // AppCacheStorage::Delegate methods.
- void OnMainResponseFound(const GURL& url,
- const AppCacheEntry& entry,
- const GURL& fallback_url,
- const AppCacheEntry& fallback_entry,
- int64_t cache_id,
- int64_t group_id,
- const GURL& manifest_url) override {
- AppCachePolicy* policy = appcache_service_->appcache_policy();
- bool was_blocked_by_policy =
- !manifest_url.is_empty() && policy &&
- !policy->CanLoadAppCache(manifest_url,
- request_.first_party_for_cookies);
-
- if (was_blocked_by_policy || !entry.has_response_id() ||
- cache_id == kAppCacheNoCacheId) {
- factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
- mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_,
- mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_));
- } else {
- DLOG(WARNING) << "AppCache found for url " << url
- << " Returning AppCache factory\n";
- // TODO(ananta)
- // Provide the plumbing to initiate AppCache requests here.
- factory_getter_->GetNetworkFactory()->get()->CreateLoaderAndStart(
- mojo::MakeRequest(&network_loader_request_), routing_id_, request_id_,
- mojom::kURLLoadOptionSendSSLInfo, request_, std::move(client_info_));
- }
- }
-
- void OnConnectionError() { delete this; }
-
- // The current request.
- ResourceRequest request_;
-
- // URLLoader proxy for the network service.
- mojom::URLLoaderAssociatedPtr network_loader_request_;
-
- // Routing id of the request. This is 0 for navigation requests. For
- // subresource requests it is non zero.
- int routing_id_;
-
- // Request id.
- int request_id_;
-
- // The URLLoaderClient pointer. We call this interface with notifications
- // about the URL load
- mojom::URLLoaderClientPtr client_info_;
-
- // Used to query AppCacheStorage to see if a request can be served out of the
- /// AppCache.
- scoped_refptr<ChromeAppCacheService> appcache_service_;
-
- // Used to retrieve the network service factory to pass requests to the
- // network service.
- scoped_refptr<URLLoaderFactoryGetter> factory_getter_;
-
- // Binds the URLLoaderClient with us.
- mojo::AssociatedBinding<mojom::URLLoader> binding_;
-
- DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoader);
-};
-
-} // namespace
-
// Implements the URLLoaderFactory mojom for AppCache requests.
AppCacheURLLoaderFactory::AppCacheURLLoaderFactory(
- ChromeAppCacheService* appcache_service,
+ mojom::URLLoaderFactoryRequest request,
URLLoaderFactoryGetter* factory_getter)
- : appcache_service_(appcache_service), factory_getter_(factory_getter) {}
+ : binding_(this, std::move(request)), factory_getter_(factory_getter) {
+ binding_.set_connection_error_handler(base::Bind(
+ &AppCacheURLLoaderFactory::OnConnectionError, base::Unretained(this)));
+}
AppCacheURLLoaderFactory::~AppCacheURLLoaderFactory() {}
// static
-void AppCacheURLLoaderFactory::CreateURLLoaderFactory(
- mojom::URLLoaderFactoryRequest request,
- ChromeAppCacheService* appcache_service,
+mojom::URLLoaderFactoryPtr AppCacheURLLoaderFactory::CreateURLLoaderFactory(
URLLoaderFactoryGetter* factory_getter) {
- std::unique_ptr<AppCacheURLLoaderFactory> factory_instance(
- new AppCacheURLLoaderFactory(appcache_service, factory_getter));
- AppCacheURLLoaderFactory* raw_factory = factory_instance.get();
- raw_factory->loader_factory_bindings_.AddBinding(std::move(factory_instance),
- std::move(request));
+ mojom::URLLoaderFactoryPtr loader_factory;
+ mojom::URLLoaderFactoryRequest request = mojo::MakeRequest(&loader_factory);
+
+ // This instance will get deleted when the client drops the connection.
+ // Please see OnConnectionError() for details.
+ new AppCacheURLLoaderFactory(std::move(request), factory_getter);
+ return loader_factory;
}
void AppCacheURLLoaderFactory::CreateLoaderAndStart(
@@ -167,12 +50,7 @@
const ResourceRequest& request,
mojom::URLLoaderClientPtr client) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // This will get deleted when the connection is dropped by the client.
- AppCacheURLLoader* loader = new AppCacheURLLoader(
- request, std::move(url_loader_request), routing_id, request_id,
- std::move(client), appcache_service_.get(), factory_getter_.get());
- loader->Start();
+ NOTREACHED() << "Currently not implemented";
}
void AppCacheURLLoaderFactory::SyncLoad(int32_t routing_id,
@@ -182,4 +60,8 @@
NOTREACHED();
}
+void AppCacheURLLoaderFactory::OnConnectionError() {
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
} // namespace content
\ No newline at end of file
diff --git a/content/browser/appcache/appcache_url_loader_factory.h b/content/browser/appcache/appcache_url_loader_factory.h
index f615395..2e39001 100644
--- a/content/browser/appcache/appcache_url_loader_factory.h
+++ b/content/browser/appcache/appcache_url_loader_factory.h
@@ -7,11 +7,13 @@
#include "base/memory/ref_counted.h"
#include "content/common/url_loader_factory.mojom.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "url/gurl.h"
namespace content {
-class ChromeAppCacheService;
+
+class AppCacheJob;
+class AppCacheServiceImpl;
class URLLoaderFactoryGetter;
// Implements the URLLoaderFactory mojom for AppCache requests.
@@ -20,13 +22,12 @@
~AppCacheURLLoaderFactory() override;
// Factory function to create an instance of the factory.
- // The |appcache_service| parameter is used to query the underlying
- // AppCacheStorage instance to check if we can service requests from the
- // AppCache. We pass unhandled requests to the network service retrieved from
- // the |factory_getter|.
- static void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request,
- ChromeAppCacheService* appcache_service,
- URLLoaderFactoryGetter* factory_getter);
+ // 1. The |factory_getter| parameter is used to query the network service
+ // to pass network requests to.
+ // Returns a URLLoaderFactoryPtr instance which controls the lifetime of the
+ // factory.
+ static mojom::URLLoaderFactoryPtr CreateURLLoaderFactory(
+ URLLoaderFactoryGetter* factory_getter);
// mojom::URLLoaderFactory implementation.
void CreateLoaderAndStart(
@@ -42,19 +43,18 @@
SyncLoadCallback callback) override;
private:
- AppCacheURLLoaderFactory(ChromeAppCacheService* appcache_service,
+ AppCacheURLLoaderFactory(mojom::URLLoaderFactoryRequest request,
URLLoaderFactoryGetter* factory_getter);
- // Used to query AppCacheStorage to see if a request can be served out of the
- /// AppCache.
- scoped_refptr<ChromeAppCacheService> appcache_service_;
+ void OnConnectionError();
+
+ // Mojo binding.
+ mojo::Binding<mojom::URLLoaderFactory> binding_;
// Used to retrieve the network service factory to pass unhandled requests to
// the network service.
scoped_refptr<URLLoaderFactoryGetter> factory_getter_;
- mojo::StrongBindingSet<mojom::URLLoaderFactory> loader_factory_bindings_;
-
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderFactory);
};
diff --git a/content/browser/appcache/appcache_url_loader_job.cc b/content/browser/appcache/appcache_url_loader_job.cc
index 09f1545..86d90fe 100644
--- a/content/browser/appcache/appcache_url_loader_job.cc
+++ b/content/browser/appcache/appcache_url_loader_job.cc
@@ -3,51 +3,288 @@
// found in the LICENSE file.
#include "content/browser/appcache/appcache_url_loader_job.h"
-#include "content/browser/appcache/appcache_entry.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/appcache/appcache_histograms.h"
+#include "content/common/net_adapters.h"
+#include "content/public/common/resource_type.h"
+#include "net/http/http_status_code.h"
namespace content {
-AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {}
+AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {
+ if (storage_.get())
+ storage_->CancelDelegateCallbacks(this);
+}
void AppCacheURLLoaderJob::Kill() {}
bool AppCacheURLLoaderJob::IsStarted() const {
- return false;
-}
-
-bool AppCacheURLLoaderJob::IsWaiting() const {
- return false;
-}
-
-bool AppCacheURLLoaderJob::IsDeliveringAppCacheResponse() const {
- return false;
-}
-
-bool AppCacheURLLoaderJob::IsDeliveringNetworkResponse() const {
- return false;
-}
-
-bool AppCacheURLLoaderJob::IsDeliveringErrorResponse() const {
- return false;
-}
-
-bool AppCacheURLLoaderJob::IsCacheEntryNotFound() const {
- return false;
+ return delivery_type_ != AWAITING_DELIVERY_ORDERS;
}
void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
const AppCacheEntry& entry,
- bool is_fallback) {}
+ bool is_fallback) {
+ if (!storage_.get()) {
+ DeliverErrorResponse();
+ return;
+ }
-void AppCacheURLLoaderJob::DeliverNetworkResponse() {}
+ delivery_type_ = APPCACHED_DELIVERY;
-void AppCacheURLLoaderJob::DeliverErrorResponse() {}
+ AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
-const GURL& AppCacheURLLoaderJob::GetURL() const {
- return url_;
+ manifest_url_ = manifest_url;
+ cache_id_ = cache_id;
+ entry_ = entry;
+ is_fallback_ = is_fallback;
+
+ // TODO(ananta)
+ // Implement the AppCacheServiceImpl::Observer interface or add weak pointer
+ // support to it.
+ storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this);
}
-AppCacheURLLoaderJob::AppCacheURLLoaderJob() {}
+void AppCacheURLLoaderJob::DeliverNetworkResponse() {
+ delivery_type_ = NETWORK_DELIVERY;
+
+ AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
+
+ DCHECK(!loader_callback_.is_null());
+ // In network service land, if we are processing a navigation request, we
+ // need to inform the loader callback that we are not going to handle this
+ // request. The loader callback is valid only for navigation requests.
+ std::move(loader_callback_).Run(StartLoaderCallback());
+}
+
+void AppCacheURLLoaderJob::DeliverErrorResponse() {
+ delivery_type_ = ERROR_DELIVERY;
+
+ // We expect the URLLoaderClient pointer to be valid at this point.
+ DCHECK(client_info_);
+
+ // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems
+ // to map to HTTP_INTERNAL_SERVER_ERROR.
+ std::string status("HTTP/1.1 ");
+ status.append(base::IntToString(net::HTTP_INTERNAL_SERVER_ERROR));
+ status.append(" ");
+ status.append(net::GetHttpReasonPhrase(net::HTTP_INTERNAL_SERVER_ERROR));
+ status.append("\0\0", 2);
+
+ ResourceResponseHead response;
+ response.headers = new net::HttpResponseHeaders(status);
+ client_info_->OnReceiveResponse(response, base::nullopt, nullptr);
+
+ NotifyCompleted(net::ERR_FAILED);
+
+ AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() -
+ start_time_tick_);
+}
+
+const GURL& AppCacheURLLoaderJob::GetURL() const {
+ return request_.url;
+}
+
+AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
+ return this;
+}
+
+void AppCacheURLLoaderJob::FollowRedirect() {
+ DCHECK(false);
+}
+
+void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) {
+ NOTREACHED() << "We don't support SetPriority()";
+}
+
+void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
+ mojom::URLLoaderClientPtr client) {
+ DCHECK(!binding_.is_bound());
+ binding_.Bind(std::move(request));
+
+ binding_.set_connection_error_handler(base::Bind(
+ &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
+
+ client_info_ = std::move(client);
+
+ // Send the cached AppCacheResponse if any.
+ if (info_.get())
+ SendResponseInfo();
+}
+
+AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request,
+ AppCacheStorage* storage)
+ : request_(request),
+ storage_(storage->GetWeakPtr()),
+ start_time_tick_(base::TimeTicks::Now()),
+ cache_id_(kAppCacheNoCacheId),
+ is_fallback_(false),
+ binding_(this),
+ writable_handle_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL) {}
+
+void AppCacheURLLoaderJob::OnResponseInfoLoaded(
+ AppCacheResponseInfo* response_info,
+ int64_t response_id) {
+ DCHECK(IsDeliveringAppCacheResponse());
+
+ if (!storage_.get()) {
+ DeliverErrorResponse();
+ return;
+ }
+
+ if (response_info) {
+ info_ = response_info;
+ reader_.reset(
+ storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
+
+ DCHECK(!loader_callback_.is_null());
+ std::move(loader_callback_)
+ .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this)));
+
+ // TODO(ananta)
+ // Handle range requests.
+
+ response_body_stream_ = std::move(data_pipe_.producer_handle);
+
+ // TODO(ananta)
+ // Move the asynchronous reading and mojo pipe handling code to a helper
+ // class. That would also need a change to BlobURLLoader.
+
+ // Wait for the data pipe to be ready to accept data.
+ writable_handle_watcher_.Watch(
+ response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady,
+ StaticAsWeakPtr(this)));
+
+ if (client_info_)
+ SendResponseInfo();
+
+ ReadMore();
+ } else {
+ // Error case here. We fallback to the network.
+ DeliverNetworkResponse();
+ AppCacheHistograms::CountResponseRetrieval(
+ false, IsResourceTypeFrame(request_.resource_type),
+ manifest_url_.GetOrigin());
+
+ cache_entry_not_found_ = true;
+ }
+}
+
+void AppCacheURLLoaderJob::OnReadComplete(int result) {
+ DLOG(WARNING) << "AppCache read completed with result: " << result;
+
+ bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
+
+ if (result == 0) {
+ NotifyCompleted(result);
+ AppCacheHistograms::CountResponseRetrieval(true, is_main_resource,
+ manifest_url_.GetOrigin());
+ return;
+ } else if (result < 0) {
+ // TODO(ananta)
+ // Populate the relevant fields of the ResourceRequestCompletionStatus
+ // structure.
+ NotifyCompleted(result);
+ AppCacheHistograms::CountResponseRetrieval(false, is_main_resource,
+ manifest_url_.GetOrigin());
+ return;
+ }
+
+ uint32_t bytes_written = static_cast<uint32_t>(result);
+ response_body_stream_ = pending_write_->Complete(bytes_written);
+ pending_write_ = nullptr;
+ ReadMore();
+}
+
+void AppCacheURLLoaderJob::OnConnectionError() {
+ if (storage_.get())
+ storage_->CancelDelegateCallbacks(this);
+ base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
+
+void AppCacheURLLoaderJob::SendResponseInfo() {
+ DCHECK(client_info_);
+
+ // If this is null it means the response information was sent to the client.
+ if (!data_pipe_.consumer_handle.is_valid())
+ return;
+
+ const net::HttpResponseInfo* http_info = info_->http_response_info();
+
+ ResourceResponseHead response_head;
+ response_head.headers = http_info->headers;
+
+ // TODO(ananta)
+ // Copy more fields.
+ http_info->headers->GetMimeType(&response_head.mime_type);
+ http_info->headers->GetCharset(&response_head.charset);
+
+ response_head.request_time = http_info->request_time;
+ response_head.response_time = http_info->response_time;
+ response_head.content_length = info_->response_data_size();
+
+ client_info_->OnReceiveResponse(response_head, http_info->ssl_info,
+ mojom::DownloadedTempFilePtr());
+
+ client_info_->OnStartLoadingResponseBody(
+ std::move(data_pipe_.consumer_handle));
+}
+
+void AppCacheURLLoaderJob::ReadMore() {
+ DCHECK(!pending_write_.get());
+
+ uint32_t num_bytes;
+ // TODO: we should use the abstractions in MojoAsyncResourceHandler.
+ MojoResult result = NetToMojoPendingBuffer::BeginWrite(
+ &response_body_stream_, &pending_write_, &num_bytes);
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ // The pipe is full. We need to wait for it to have more space.
+ writable_handle_watcher_.ArmOrNotify();
+ return;
+ } else if (result != MOJO_RESULT_OK) {
+ // The response body stream is in a bad state. Bail.
+ // TODO(ananta)
+ // Add proper error handling here.
+ NotifyCompleted(net::ERR_FAILED);
+ writable_handle_watcher_.Cancel();
+ response_body_stream_.reset();
+ return;
+ }
+
+ CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
+ scoped_refptr<NetToMojoIOBuffer> buffer =
+ new NetToMojoIOBuffer(pending_write_.get());
+
+ reader_->ReadData(
+ buffer.get(), info_->response_data_size(),
+ base::Bind(&AppCacheURLLoaderJob::OnReadComplete, StaticAsWeakPtr(this)));
+}
+
+void AppCacheURLLoaderJob::OnResponseBodyStreamReady(MojoResult result) {
+ // TODO(ananta)
+ // Add proper error handling here.
+ if (result != MOJO_RESULT_OK) {
+ DCHECK(false);
+ NotifyCompleted(net::ERR_FAILED);
+ }
+ ReadMore();
+}
+
+void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
+ if (storage_.get())
+ storage_->CancelDelegateCallbacks(this);
+ // TODO(ananta)
+ // Fill other details in the ResourceRequestCompletionStatus structure.
+ ResourceRequestCompletionStatus request_complete_data;
+ request_complete_data.error_code = error_code;
+ client_info_->OnComplete(request_complete_data);
+}
} // namespace content
diff --git a/content/browser/appcache/appcache_url_loader_job.h b/content/browser/appcache/appcache_url_loader_job.h
index 3d526c9..3a1e125 100644
--- a/content/browser/appcache/appcache_url_loader_job.h
+++ b/content/browser/appcache/appcache_url_loader_job.h
@@ -6,30 +6,40 @@
#define CONTENT_BROWSER_APPCACHE_APPCACHE_URL_LOADER_JOB_H_
#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
+#include "base/time/time.h"
+#include "content/browser/appcache/appcache_entry.h"
#include "content/browser/appcache/appcache_job.h"
+#include "content/browser/appcache/appcache_response.h"
+#include "content/browser/appcache/appcache_storage.h"
+#include "content/browser/loader/url_loader_request_handler.h"
#include "content/common/content_export.h"
+#include "content/common/resource_request.h"
+#include "content/common/url_loader.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/data_pipe.h"
namespace content {
-class AppCacheHost;
class AppCacheRequest;
-class AppCacheStorage;
+class NetToMojoPendingBuffer;
// AppCacheJob wrapper for a mojom::URLLoader implementation which returns
// responses stored in the AppCache.
-class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob {
+class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
+ public AppCacheStorage::Delegate,
+ public mojom::URLLoader {
public:
~AppCacheURLLoaderJob() override;
+ // Sets up the bindings.
+ void Start(mojom::URLLoaderRequest request, mojom::URLLoaderClientPtr client);
+
// AppCacheJob overrides.
void Kill() override;
bool IsStarted() const override;
- bool IsWaiting() const override;
- bool IsDeliveringAppCacheResponse() const override;
- bool IsDeliveringNetworkResponse() const override;
- bool IsDeliveringErrorResponse() const override;
- bool IsCacheEntryNotFound() const override;
void DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
const AppCacheEntry& entry,
@@ -37,14 +47,90 @@
void DeliverNetworkResponse() override;
void DeliverErrorResponse() override;
const GURL& GetURL() const override;
+ AppCacheURLLoaderJob* AsURLLoaderJob() override;
+
+ // mojom::URLLoader implementation:
+ void FollowRedirect() override;
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override;
+
+ void set_loader_callback(LoaderCallback callback) {
+ loader_callback_ = std::move(callback);
+ }
protected:
// AppCacheJob::Create() creates this instance.
friend class AppCacheJob;
- AppCacheURLLoaderJob();
+ AppCacheURLLoaderJob(const ResourceRequest& request,
+ AppCacheStorage* storage);
- GURL url_;
+ // AppCacheStorage::Delegate methods
+ void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
+ int64_t response_id) override;
+
+ // AppCacheResponseReader completion callback
+ void OnReadComplete(int result);
+
+ void OnConnectionError();
+
+ // Helper to send the AppCacheResponseInfo to the URLLoaderClient.
+ void SendResponseInfo();
+
+ // Helper function to read the data from the AppCache.
+ void ReadMore();
+
+ // Callback invoked when the data pipe can be written to.
+ void OnResponseBodyStreamReady(MojoResult result);
+
+ // Notifies the client about request completion.
+ void NotifyCompleted(int error_code);
+
+ // The current request.
+ ResourceRequest request_;
+
+ base::WeakPtr<AppCacheStorage> storage_;
+
+ // The response details.
+ scoped_refptr<AppCacheResponseInfo> info_;
+
+ // Used to read the cache.
+ std::unique_ptr<AppCacheResponseReader> reader_;
+
+ // Time when the request started.
+ base::TimeTicks start_time_tick_;
+
+ // The AppCache manifest URL.
+ GURL manifest_url_;
+
+ // The AppCache id.
+ int64_t cache_id_;
+
+ AppCacheEntry entry_;
+
+ // Set to true if we are loading fallback content.
+ bool is_fallback_;
+
+ // The data pipe used to transfer AppCache data to the client.
+ mojo::DataPipe data_pipe_;
+
+ // Binds the URLLoaderClient with us.
+ mojo::Binding<mojom::URLLoader> binding_;
+
+ // The URLLoaderClient pointer. We call this interface with notifications
+ // about the URL load
+ mojom::URLLoaderClientPtr client_info_;
+
+ // mojo data pipe entities.
+ mojo::ScopedDataPipeProducerHandle response_body_stream_;
+
+ scoped_refptr<NetToMojoPendingBuffer> pending_write_;
+
+ mojo::SimpleWatcher writable_handle_watcher_;
+
+ // The Callback to be invoked in the network service land to indicate if
+ // the request can be serviced via the AppCache.
+ LoaderCallback loader_callback_;
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderJob);
};
diff --git a/content/browser/appcache/appcache_url_loader_request.cc b/content/browser/appcache/appcache_url_loader_request.cc
index c85de029..11c85ba 100644
--- a/content/browser/appcache/appcache_url_loader_request.cc
+++ b/content/browser/appcache/appcache_url_loader_request.cc
@@ -9,27 +9,27 @@
// static
std::unique_ptr<AppCacheURLLoaderRequest> AppCacheURLLoaderRequest::Create(
- std::unique_ptr<ResourceRequest> request) {
+ const ResourceRequest& request) {
return std::unique_ptr<AppCacheURLLoaderRequest>(
- new AppCacheURLLoaderRequest(std::move(request)));
+ new AppCacheURLLoaderRequest(request));
}
AppCacheURLLoaderRequest::~AppCacheURLLoaderRequest() {}
const GURL& AppCacheURLLoaderRequest::GetURL() const {
- return request_->url;
+ return request_.url;
}
const std::string& AppCacheURLLoaderRequest::GetMethod() const {
- return request_->method;
+ return request_.method;
}
const GURL& AppCacheURLLoaderRequest::GetFirstPartyForCookies() const {
- return request_->first_party_for_cookies;
+ return request_.first_party_for_cookies;
}
const GURL AppCacheURLLoaderRequest::GetReferrer() const {
- return request_->referrer;
+ return request_.referrer;
}
bool AppCacheURLLoaderRequest::IsSuccess() const {
@@ -54,11 +54,11 @@
}
ResourceRequest* AppCacheURLLoaderRequest::GetResourceRequest() {
- return request_.get();
+ return &request_;
}
AppCacheURLLoaderRequest::AppCacheURLLoaderRequest(
- std::unique_ptr<ResourceRequest> request)
- : request_(std::move(request)) {}
+ const ResourceRequest& request)
+ : request_(request) {}
} // namespace content
diff --git a/content/browser/appcache/appcache_url_loader_request.h b/content/browser/appcache/appcache_url_loader_request.h
index 13581f1..97e3f77 100644
--- a/content/browser/appcache/appcache_url_loader_request.h
+++ b/content/browser/appcache/appcache_url_loader_request.h
@@ -17,7 +17,7 @@
// Factory function to create an instance of the AppCacheResourceRequest
// class.
static std::unique_ptr<AppCacheURLLoaderRequest> Create(
- std::unique_ptr<ResourceRequest> request);
+ const ResourceRequest& request);
~AppCacheURLLoaderRequest() override;
@@ -38,14 +38,13 @@
bool IsError() const override;
int GetResponseCode() const override;
std::string GetResponseHeaderByName(const std::string& name) const override;
-
ResourceRequest* GetResourceRequest() override;
protected:
- explicit AppCacheURLLoaderRequest(std::unique_ptr<ResourceRequest> request);
+ explicit AppCacheURLLoaderRequest(const ResourceRequest& request);
private:
- std::unique_ptr<ResourceRequest> request_;
+ ResourceRequest request_;
DISALLOW_COPY_AND_ASSIGN(AppCacheURLLoaderRequest);
};
diff --git a/content/browser/appcache/appcache_url_request_job.cc b/content/browser/appcache/appcache_url_request_job.cc
index 8a89def..b17d3d77 100644
--- a/content/browser/appcache/appcache_url_request_job.cc
+++ b/content/browser/appcache/appcache_url_request_job.cc
@@ -60,26 +60,6 @@
return has_been_started_;
}
-bool AppCacheURLRequestJob::IsWaiting() const {
- return delivery_type_ == AWAITING_DELIVERY_ORDERS;
-}
-
-bool AppCacheURLRequestJob::IsDeliveringAppCacheResponse() const {
- return delivery_type_ == APPCACHED_DELIVERY;
-}
-
-bool AppCacheURLRequestJob::IsDeliveringNetworkResponse() const {
- return delivery_type_ == NETWORK_DELIVERY;
-}
-
-bool AppCacheURLRequestJob::IsDeliveringErrorResponse() const {
- return delivery_type_ == ERROR_DELIVERY;
-}
-
-bool AppCacheURLRequestJob::IsCacheEntryNotFound() const {
- return cache_entry_not_found_;
-}
-
void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
const AppCacheEntry& entry,
@@ -128,11 +108,9 @@
storage_(storage),
has_been_started_(false),
has_been_killed_(false),
- delivery_type_(AWAITING_DELIVERY_ORDERS),
cache_id_(kAppCacheNoCacheId),
is_fallback_(false),
is_main_resource_(is_main_resource),
- cache_entry_not_found_(false),
on_prepare_to_restart_callback_(restart_callback) {
DCHECK(storage_);
}
diff --git a/content/browser/appcache/appcache_url_request_job.h b/content/browser/appcache/appcache_url_request_job.h
index 56b3cfa..f4f23a7 100644
--- a/content/browser/appcache/appcache_url_request_job.h
+++ b/content/browser/appcache/appcache_url_request_job.h
@@ -44,11 +44,6 @@
// AppCacheJob overrides.
void Kill() override;
bool IsStarted() const override;
- bool IsWaiting() const override;
- bool IsDeliveringAppCacheResponse() const override;
- bool IsDeliveringNetworkResponse() const override;
- bool IsDeliveringErrorResponse() const override;
- bool IsCacheEntryNotFound() const override;
void DeliverAppCachedResponse(const GURL& manifest_url,
int64_t cache_id,
const AppCacheEntry& entry,
@@ -83,13 +78,6 @@
bool is_main_resource,
const OnPrepareToRestartCallback& restart_callback_);
- enum DeliveryType {
- AWAITING_DELIVERY_ORDERS,
- APPCACHED_DELIVERY,
- NETWORK_DELIVERY,
- ERROR_DELIVERY
- };
-
// Returns true if one of the Deliver methods has been called.
bool has_delivery_orders() const { return !IsWaiting(); }
@@ -140,13 +128,11 @@
base::TimeTicks start_time_tick_;
bool has_been_started_;
bool has_been_killed_;
- DeliveryType delivery_type_;
GURL manifest_url_;
int64_t cache_id_;
AppCacheEntry entry_;
bool is_fallback_;
bool is_main_resource_; // Used for histogram logging.
- bool cache_entry_not_found_;
scoped_refptr<AppCacheResponseInfo> info_;
scoped_refptr<net::GrowableIOBuffer> handler_source_buffer_;
std::unique_ptr<AppCacheResponseReader> handler_source_reader_;
diff --git a/content/browser/appcache/mock_appcache_storage.cc b/content/browser/appcache/mock_appcache_storage.cc
index a5c5382..1bd3bed5 100644
--- a/content/browser/appcache/mock_appcache_storage.cc
+++ b/content/browser/appcache/mock_appcache_storage.cc
@@ -201,6 +201,10 @@
}
}
+bool MockAppCacheStorage::IsInitialized() {
+ return false;
+}
+
void MockAppCacheStorage::ProcessGetAllInfo(
scoped_refptr<DelegateReference> delegate_ref) {
if (delegate_ref->delegate)
diff --git a/content/browser/appcache/mock_appcache_storage.h b/content/browser/appcache/mock_appcache_storage.h
index b19404b..d8a6ee3 100644
--- a/content/browser/appcache/mock_appcache_storage.h
+++ b/content/browser/appcache/mock_appcache_storage.h
@@ -81,6 +81,7 @@
const std::vector<int64_t>& response_ids) override;
void DeleteResponses(const GURL& manifest_url,
const std::vector<int64_t>& response_ids) override;
+ bool IsInitialized() override;
private:
friend class AppCacheRequestHandlerTest;
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index e9e9ac9..e358cb19 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -9,6 +9,7 @@
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
+#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_request_info.h"
@@ -166,7 +167,11 @@
}
if (appcache_handle_core) {
- // TODO: add appcache code here.
+ std::unique_ptr<URLLoaderRequestHandler> appcache_handler =
+ AppCacheRequestHandler::InitializeForNavigationNetworkService(
+ *resource_request_, appcache_handle_core);
+ if (appcache_handler)
+ handlers_.push_back(std::move(appcache_handler));
}
Restart(std::move(url_loader_request), std::move(url_loader_client_ptr_));
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc
index 4cf6d39..d5013516 100644
--- a/content/browser/url_loader_factory_getter.cc
+++ b/content/browser/url_loader_factory_getter.cc
@@ -5,7 +5,6 @@
#include "content/browser/url_loader_factory_getter.h"
#include "base/bind.h"
-#include "content/browser/appcache/appcache_url_loader_factory.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/network_service.mojom.h"
@@ -26,9 +25,7 @@
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread, this,
network_factory.PassInterface(),
- blob_factory.PassInterface(),
- scoped_refptr<ChromeAppCacheService>(
- partition->GetAppCacheService())));
+ blob_factory.PassInterface()));
}
mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetNetworkFactory() {
@@ -52,22 +49,13 @@
this, test_factory.PassInterface()));
}
-mojom::URLLoaderFactoryPtr* URLLoaderFactoryGetter::GetAppCacheFactory() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return &appcache_factory_;
-}
-
URLLoaderFactoryGetter::~URLLoaderFactoryGetter() {}
void URLLoaderFactoryGetter::InitializeOnIOThread(
mojom::URLLoaderFactoryPtrInfo network_factory,
- mojom::URLLoaderFactoryPtrInfo blob_factory,
- scoped_refptr<ChromeAppCacheService> appcache_service) {
+ mojom::URLLoaderFactoryPtrInfo blob_factory) {
network_factory_.Bind(std::move(network_factory));
blob_factory_.Bind(std::move(blob_factory));
-
- AppCacheURLLoaderFactory::CreateURLLoaderFactory(
- mojo::MakeRequest(&appcache_factory_), appcache_service.get(), this);
}
void URLLoaderFactoryGetter::SetTestNetworkFactoryOnIOThread(
diff --git a/content/browser/url_loader_factory_getter.h b/content/browser/url_loader_factory_getter.h
index 0af16fd..1ea7281 100644
--- a/content/browser/url_loader_factory_getter.h
+++ b/content/browser/url_loader_factory_getter.h
@@ -13,7 +13,6 @@
namespace content {
-class ChromeAppCacheService;
class StoragePartitionImpl;
// Holds on to URLLoaderFactory for a given StoragePartition and allows code
@@ -43,25 +42,18 @@
CONTENT_EXPORT void SetNetworkFactoryForTesting(
mojom::URLLoaderFactoryPtr test_factory);
- // Called on the IO thread to get the URLLoaderFactory for AppCache. The
- // pointer should not be cached.
- mojom::URLLoaderFactoryPtr* GetAppCacheFactory();
-
private:
friend class base::DeleteHelper<URLLoaderFactoryGetter>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
CONTENT_EXPORT ~URLLoaderFactoryGetter();
- void InitializeOnIOThread(
- mojom::URLLoaderFactoryPtrInfo network_factory,
- mojom::URLLoaderFactoryPtrInfo blob_factory,
- scoped_refptr<ChromeAppCacheService> appcache_service);
+ void InitializeOnIOThread(mojom::URLLoaderFactoryPtrInfo network_factory,
+ mojom::URLLoaderFactoryPtrInfo blob_factory);
void SetTestNetworkFactoryOnIOThread(
mojom::URLLoaderFactoryPtrInfo test_factory);
// Only accessed on IO thread.
mojom::URLLoaderFactoryPtr network_factory_;
- mojom::URLLoaderFactoryPtr appcache_factory_;
mojom::URLLoaderFactoryPtr blob_factory_;
mojom::URLLoaderFactoryPtr test_factory_;