Commit da9aac88 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

PlzWorker: Support AppCache's fallback case for shared workers

This CL makes SharedWorkerScriptFetcher ask network interceptors if they want
to handle a response served by the default network loader. This is necessary for
supporting AppCache's fallback.

A possible confusing point of this CL is
SharedWorkerScriptFetcher::OnReceiveResponse() can be called twice. First, it's
called when the interceptor or the default network loader serves the shared
worker's main script. Then, it's called again when the interceptor wants to
serve an alternative response for the response served by the default network
loader.

Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: I93b45fa1f2e42422c0e85d3a67471c891dc5992a
Bug: 715632
Reviewed-on: https://chromium-review.googlesource.com/c/1224611Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#596122}
parent df242b02
...@@ -600,6 +600,8 @@ bool AppCacheRequestHandler::MaybeCreateLoaderForResponse( ...@@ -600,6 +600,8 @@ bool AppCacheRequestHandler::MaybeCreateLoaderForResponse(
return false; return false;
} }
DCHECK(was_called); DCHECK(was_called);
if (IsMainResourceType(resource_type_))
should_create_subresource_loader_ = true;
return true; return true;
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "content/browser/shared_worker/shared_worker_script_loader.h" #include "content/browser/shared_worker/shared_worker_script_loader.h"
#include "content/browser/shared_worker/shared_worker_script_loader_factory.h" #include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/throttling_url_loader.h" #include "content/common/throttling_url_loader.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/common/url_loader_throttle.h" #include "content/public/common/url_loader_throttle.h"
...@@ -71,7 +70,8 @@ SharedWorkerScriptFetcher::SharedWorkerScriptFetcher( ...@@ -71,7 +70,8 @@ SharedWorkerScriptFetcher::SharedWorkerScriptFetcher(
CreateAndStartCallback callback) CreateAndStartCallback callback)
: script_loader_factory_(std::move(script_loader_factory)), : script_loader_factory_(std::move(script_loader_factory)),
resource_request_(std::move(resource_request)), resource_request_(std::move(resource_request)),
callback_(std::move(callback)) { callback_(std::move(callback)),
response_url_loader_binding_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
} }
...@@ -104,14 +104,49 @@ void SharedWorkerScriptFetcher::OnReceiveResponse( ...@@ -104,14 +104,49 @@ void SharedWorkerScriptFetcher::OnReceiveResponse(
const network::ResourceResponseHead& head) { const network::ResourceResponseHead& head) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(nhiroki): Support AppCache's fallback case. See base::WeakPtr<SharedWorkerScriptLoader> script_loader =
// NavigationLoaderInterceptor::MaybeCreateLoaderForResponse() for script_loader_factory_->GetScriptLoader();
// reference (https://crbug.com/715632). if (script_loader && script_loader->default_loader_used_) {
// If the default network loader was used to handle the URL load request we
// need to see if the request interceptors want to potentially create a new
// loader for the response, e.g. AppCache's fallback.
DCHECK(!response_url_loader_);
network::mojom::URLLoaderClientRequest response_client_request;
if (script_loader->MaybeCreateLoaderForResponse(head, &response_url_loader_,
&response_client_request,
url_loader_.get())) {
DCHECK(response_url_loader_);
response_url_loader_binding_.Bind(std::move(response_client_request));
subresource_loader_params_ = script_loader->TakeSubresourceLoaderParams();
url_loader_.reset();
// OnReceiveResponse() will be called again.
return;
}
}
blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params = blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params =
blink::mojom::SharedWorkerMainScriptLoadParams::New(); blink::mojom::SharedWorkerMainScriptLoadParams::New();
// Fill in params for loading shared worker's main script and subresources.
main_script_load_params->response_head = head; main_script_load_params->response_head = head;
main_script_load_params->url_loader_client_endpoints = url_loader_->Unbind(); if (url_loader_) {
// The main script was served by a request interceptor or the default
// network loader.
DCHECK(!response_url_loader_);
main_script_load_params->url_loader_client_endpoints =
url_loader_->Unbind();
subresource_loader_params_ = script_loader->TakeSubresourceLoaderParams();
} else {
// The main script was served by the default network loader first, and then
// a request interceptor created another loader |response_url_loader_| for
// serving an alternative response.
DCHECK(response_url_loader_);
DCHECK(response_url_loader_binding_.is_bound());
main_script_load_params->url_loader_client_endpoints =
network::mojom::URLLoaderClientEndpoints::New(
response_url_loader_.PassInterface(),
response_url_loader_binding_.Unbind());
}
for (size_t i = 0; i < redirect_infos_.size(); ++i) { for (size_t i = 0; i < redirect_infos_.size(); ++i) {
main_script_load_params->redirect_infos.emplace_back(redirect_infos_[i]); main_script_load_params->redirect_infos.emplace_back(redirect_infos_[i]);
...@@ -119,11 +154,8 @@ void SharedWorkerScriptFetcher::OnReceiveResponse( ...@@ -119,11 +154,8 @@ void SharedWorkerScriptFetcher::OnReceiveResponse(
redirect_response_heads_[i]); redirect_response_heads_[i]);
} }
base::Optional<SubresourceLoaderParams> subresource_loader_params =
script_loader_factory_->TakeSubresourceLoaderParams();
std::move(callback_).Run(std::move(main_script_load_params), std::move(callback_).Run(std::move(main_script_load_params),
std::move(subresource_loader_params), std::move(subresource_loader_params_),
true /* success */); true /* success */);
delete this; delete this;
} }
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/optional.h" #include "base/optional.h"
#include "content/common/navigation_subresource_loader_params.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/url_request/redirect_info.h" #include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_loader.mojom.h"
...@@ -22,7 +24,6 @@ namespace content { ...@@ -22,7 +24,6 @@ namespace content {
class SharedWorkerScriptLoaderFactory; class SharedWorkerScriptLoaderFactory;
class ThrottlingURLLoader; class ThrottlingURLLoader;
class URLLoaderThrottle; class URLLoaderThrottle;
struct SubresourceLoaderParams;
// NetworkService (PlzWorker): // NetworkService (PlzWorker):
// This is an implementation of the URLLoaderClient for shared worker's main // This is an implementation of the URLLoaderClient for shared worker's main
...@@ -71,10 +72,22 @@ class SharedWorkerScriptFetcher : public network::mojom::URLLoaderClient { ...@@ -71,10 +72,22 @@ class SharedWorkerScriptFetcher : public network::mojom::URLLoaderClient {
void OnComplete(const network::URLLoaderCompletionStatus& status) override; void OnComplete(const network::URLLoaderCompletionStatus& status) override;
std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory_; std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory_;
std::unique_ptr<network::ResourceRequest> resource_request_; std::unique_ptr<network::ResourceRequest> resource_request_;
CreateAndStartCallback callback_; CreateAndStartCallback callback_;
// URLLoader instance backed by a request interceptor (e.g.,
// AppCacheRequestHandler) or the network service.
std::unique_ptr<ThrottlingURLLoader> url_loader_; std::unique_ptr<ThrottlingURLLoader> url_loader_;
// URLLoader instance for handling a response received from the default
// network loader. This can be provided by an interceptor. For example,
// AppCache's interceptor creates this for AppCache's fallback case.
network::mojom::URLLoaderPtr response_url_loader_;
mojo::Binding<network::mojom::URLLoaderClient> response_url_loader_binding_;
base::Optional<SubresourceLoaderParams> subresource_loader_params_;
std::vector<net::RedirectInfo> redirect_infos_; std::vector<net::RedirectInfo> redirect_infos_;
std::vector<network::ResourceResponseHead> redirect_response_heads_; std::vector<network::ResourceResponseHead> redirect_response_heads_;
}; };
......
...@@ -117,6 +117,7 @@ void SharedWorkerScriptLoader::MaybeStartLoader( ...@@ -117,6 +117,7 @@ void SharedWorkerScriptLoader::MaybeStartLoader(
void SharedWorkerScriptLoader::LoadFromNetwork( void SharedWorkerScriptLoader::LoadFromNetwork(
bool reset_subresource_loader_params) { bool reset_subresource_loader_params) {
default_loader_used_ = true;
network::mojom::URLLoaderClientPtr client; network::mojom::URLLoaderClientPtr client;
if (url_loader_client_binding_) if (url_loader_client_binding_)
url_loader_client_binding_.Unbind(); url_loader_client_binding_.Unbind();
...@@ -245,4 +246,22 @@ void SharedWorkerScriptLoader::OnComplete( ...@@ -245,4 +246,22 @@ void SharedWorkerScriptLoader::OnComplete(
client_->OnComplete(status); client_->OnComplete(status);
} }
bool SharedWorkerScriptLoader::MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* response_url_loader,
network::mojom::URLLoaderClientRequest* response_client_request,
ThrottlingURLLoader* url_loader) {
DCHECK(default_loader_used_);
for (auto& interceptor : interceptors_) {
if (interceptor->MaybeCreateLoaderForResponse(response, response_url_loader,
response_client_request,
url_loader)) {
subresource_loader_params_ =
interceptor->MaybeCreateSubresourceLoaderParams();
return true;
}
}
return false;
}
} // namespace content } // namespace content
...@@ -20,6 +20,7 @@ class SharedURLLoaderFactory; ...@@ -20,6 +20,7 @@ class SharedURLLoaderFactory;
namespace content { namespace content {
class AppCacheHost; class AppCacheHost;
class ThrottlingURLLoader;
class NavigationLoaderInterceptor; class NavigationLoaderInterceptor;
class ResourceContext; class ResourceContext;
class ServiceWorkerProviderHost; class ServiceWorkerProviderHost;
...@@ -83,12 +84,25 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader, ...@@ -83,12 +84,25 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
mojo::ScopedDataPipeConsumerHandle body) override; mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override; void OnComplete(const network::URLLoaderCompletionStatus& status) override;
// Returns a URLLoader client endpoint if an interceptor wants to handle the
// response, i.e. return a different response. For e.g. AppCache may have
// fallback content.
bool MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* response_url_loader,
network::mojom::URLLoaderClientRequest* response_client_request,
ThrottlingURLLoader* url_loader);
base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams() { base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams() {
return std::move(subresource_loader_params_); return std::move(subresource_loader_params_);
} }
base::WeakPtr<SharedWorkerScriptLoader> GetWeakPtr(); base::WeakPtr<SharedWorkerScriptLoader> GetWeakPtr();
// Set to true if the default URLLoader (network service) was used for the
// current request.
bool default_loader_used_ = false;
private: private:
void Start(); void Start();
void MaybeStartLoader( void MaybeStartLoader(
......
...@@ -89,10 +89,4 @@ void SharedWorkerScriptLoaderFactory::Clone( ...@@ -89,10 +89,4 @@ void SharedWorkerScriptLoaderFactory::Clone(
NOTREACHED(); NOTREACHED();
} }
base::Optional<SubresourceLoaderParams>
SharedWorkerScriptLoaderFactory::TakeSubresourceLoaderParams() {
DCHECK(script_loader_);
return script_loader_->TakeSubresourceLoaderParams();
}
} // namespace content } // namespace content
...@@ -59,7 +59,9 @@ class SharedWorkerScriptLoaderFactory ...@@ -59,7 +59,9 @@ class SharedWorkerScriptLoaderFactory
traffic_annotation) override; traffic_annotation) override;
void Clone(network::mojom::URLLoaderFactoryRequest request) override; void Clone(network::mojom::URLLoaderFactoryRequest request) override;
base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams(); base::WeakPtr<SharedWorkerScriptLoader> GetScriptLoader() {
return script_loader_;
}
private: private:
const int process_id_; const int process_id_;
......
# These tests currently fail when run with --enable-features=NetworkSerivce # These tests currently fail when run with --enable-features=NetworkSerivce
# See https://crbug.com/729849 # See https://crbug.com/729849
crbug.com/829417 external/wpt/html/browsers/offline/appcache/workers/appcache-worker.https.html [ Timeout ]
Bug(none) http/tests/security/cors-rfc1918 [ Crash Timeout ] Bug(none) http/tests/security/cors-rfc1918 [ Crash Timeout ]
Bug(none) http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html [ Pass Timeout ] Bug(none) http/tests/security/powerfulFeatureRestrictions/old-powerful-features-on-insecure-origin.html [ Pass Timeout ]
Bug(none) virtual/outofblink-cors/http/tests/security/cors-rfc1918 [ Crash Timeout ] Bug(none) virtual/outofblink-cors/http/tests/security/cors-rfc1918 [ Crash Timeout ]
......
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