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

Side by Side Diff: content/browser/service_worker/service_worker_url_job_wrapper.cc

Issue 2906163002: [network service][SW] Rework browser-side SW on top of URL loader chaining (Closed)
Patch Set: fixes Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_url_job_wrapper.h" 5 #include "content/browser/service_worker/service_worker_url_job_wrapper.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "content/browser/service_worker/service_worker_response_type.h" 8 #include "content/browser/service_worker/service_worker_response_type.h"
9 #include "content/browser/service_worker/service_worker_version.h"
10 #include "content/common/service_worker/service_worker_utils.h"
11 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/resource_request_info.h" 12 #include "content/public/browser/resource_request_info.h"
10 #include "content/public/common/browser_side_navigation_policy.h" 13 #include "content/public/common/browser_side_navigation_policy.h"
11 #include "content/public/common/content_switches.h" 14 #include "content/public/common/content_switches.h"
15 #include "mojo/public/cpp/bindings/strong_associated_binding.h"
16 #include "net/base/io_buffer.h"
17 #include "storage/browser/blob/blob_storage_context.h"
12 18
13 namespace content { 19 namespace content {
14 20
21 namespace {
22
23 class URLLoaderImpl : public mojom::URLLoader {
24 public:
25 URLLoaderImpl(const ServiceWorkerResponse& response,
26 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
27 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
28 mojom::URLLoaderClientPtr url_loader_client)
29 : blob_storage_context_(blob_storage_context),
30 url_loader_client_(std::move(url_loader_client)),
31 weak_factory_(this) {
32 ResourceResponseHead head;
33 // TODO(scottmg): More fields in |head| required?
34 head.headers = new net::HttpResponseHeaders("");
35 for (const auto& kv : response.headers)
36 head.headers->AddHeader(kv.first + ": " + kv.second);
37 head.url_list_via_service_worker = response.url_list;
38 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
39 head.was_fetched_via_service_worker = true;
40 head.cors_exposed_header_names = response.cors_exposed_header_names;
41 url_loader_client_->OnReceiveResponse(
42 head, base::nullopt /* TODO(scottmg): ssl info */,
43 mojom::DownloadedTempFilePtr());
44
45 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use
46 // this case. See:
47 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5 yyLjfld0KvKchVfA84Y/edit?usp=drive_web
48 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
49 url_loader_client_->OnStartLoadingResponseBody(
50 std::move(body_as_stream->stream));
51 } else {
52 // TODO(scottmg): This is temporary way to load the blob right here and
53 // turn it into a data pipe to respond with, until we are always able to
54 // take the above path.
55 if (!response.blob_uuid.empty() && blob_storage_context_) {
56 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
57 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
58 blob_reader_ = blob_data_handle->CreateReader(
59 nullptr /* file system context */,
60 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
61 CHECK(storage::BlobReader::Status::DONE ==
62 blob_reader_->CalculateSize(net::CompletionCallback()));
63 blob_reader_->SetReadRange(0, blob_reader_->total_size());
64 scoped_refptr<net::IOBuffer> buffer(
65 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
66
67 int bytes_read;
68 blob_reader_->Read(buffer.get(), blob_reader_->total_size(),
69 &bytes_read,
70 base::Bind(&URLLoaderImpl::AfterRead,
71 weak_factory_.GetWeakPtr(), buffer));
72 }
73 }
74 }
75
76 // mojom::URLLoader:
77 void FollowRedirect() override { NOTIMPLEMENTED(); }
78
79 void SetPriority(net::RequestPriority priority,
80 int32_t intra_priority_value) override {
81 NOTIMPLEMENTED();
82 }
83
84 private:
85 void AfterRead(scoped_refptr<net::IOBuffer> buffer, int bytes) {
86 uint32_t bytes_written = static_cast<uint32_t>(bytes);
87 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
88 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
89 url_loader_client_->OnStartLoadingResponseBody(
90 std::move(data_pipe_.consumer_handle));
91 }
92
93 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
94 mojom::URLLoaderClientPtr url_loader_client_;
95 std::unique_ptr<storage::BlobReader> blob_reader_;
96 mojo::DataPipe data_pipe_;
97
98 base::WeakPtrFactory<URLLoaderImpl> weak_factory_;
99
100 DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
101 };
102
103 } // namespace
104
105 class ServiceWorkerURLJobWrapper::Factory : public mojom::URLLoaderFactory {
106 public:
107 Factory(const ServiceWorkerResponse& response,
108 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
109 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
110 : response_(response),
111 body_as_stream_(std::move(body_as_stream)),
112 blob_storage_context_(blob_storage_context) {}
113
114 void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest request,
115 int32_t routing_id,
116 int32_t request_id,
117 uint32_t options,
118 const ResourceRequest& url_request,
119 mojom::URLLoaderClientPtr client) override {
120 // Note that url_request is ignored here, as we've already processed the
121 // fetch before even creating the factory.
122 // TODO(scottmg): Use options.
123 mojo::MakeStrongAssociatedBinding(
124 base::MakeUnique<URLLoaderImpl>(response_, std::move(body_as_stream_),
125 blob_storage_context_,
126 std::move(client)),
127 std::move(request));
128 }
129
130 void SyncLoad(int32_t routing_id,
131 int32_t request_id,
132 const ResourceRequest& url_request,
133 SyncLoadCallback callback) override {
134 NOTREACHED();
135 }
136
137 private:
138 ServiceWorkerResponse response_;
139 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream_;
140 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
141
142 DISALLOW_COPY_AND_ASSIGN(Factory);
143 };
144
15 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper( 145 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
16 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job) 146 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job)
17 : job_type_(JobType::kURLRequest), 147 : job_type_(JobType::kURLRequest),
18 url_request_job_(std::move(url_request_job)), 148 url_request_job_(std::move(url_request_job)),
19 weak_factory_(this) {} 149 weak_factory_(this) {}
20 150
21 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper( 151 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
22 LoaderFactoryCallback callback) 152 LoaderFactoryCallback callback,
153 Delegate* delegate,
154 const ResourceRequest& resource_request,
155 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
23 : job_type_(JobType::kURLLoader), 156 : job_type_(JobType::kURLLoader),
24 loader_factory_callback_(std::move(callback)), 157 loader_factory_callback_(std::move(callback)),
158 delegate_(delegate),
159 resource_request_(resource_request),
160 blob_storage_context_(blob_storage_context),
25 weak_factory_(this) { 161 weak_factory_(this) {
26 DCHECK(IsBrowserSideNavigationEnabled() && 162 DCHECK(IsBrowserSideNavigationEnabled() &&
27 base::CommandLine::ForCurrentProcess()->HasSwitch( 163 base::CommandLine::ForCurrentProcess()->HasSwitch(
28 switches::kEnableNetworkService)); 164 switches::kEnableNetworkService));
29 } 165 }
30 166
31 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {} 167 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {}
32 168
33 void ServiceWorkerURLJobWrapper::FallbackToNetwork() { 169 void ServiceWorkerURLJobWrapper::FallbackToNetwork() {
34 if (job_type_ == JobType::kURLLoader) { 170 if (job_type_ == JobType::kURLLoader) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 bool ServiceWorkerURLJobWrapper::WasCanceled() const { 241 bool ServiceWorkerURLJobWrapper::WasCanceled() const {
106 if (job_type_ == JobType::kURLLoader) { 242 if (job_type_ == JobType::kURLLoader) {
107 return loader_factory_callback_.is_null(); 243 return loader_factory_callback_.is_null();
108 } else { 244 } else {
109 return !url_request_job_; 245 return !url_request_job_;
110 } 246 }
111 } 247 }
112 248
113 void ServiceWorkerURLJobWrapper::StartRequest() { 249 void ServiceWorkerURLJobWrapper::StartRequest() {
114 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_); 250 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_);
115 // TODO(kinuko): Implement. For now we just exercise async fall back path 251
116 // to the network. 252 ServiceWorkerMetrics::URLRequestJobResult result =
117 base::ThreadTaskRunnerHandle::Get()->PostTask( 253 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
118 FROM_HERE, base::Bind(&ServiceWorkerURLJobWrapper::FallbackToNetwork, 254 ServiceWorkerVersion* active_worker =
119 weak_factory_.GetWeakPtr())); 255 delegate_->GetServiceWorkerVersion(&result);
256
257 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
258 CreateFetchRequest(resource_request_), active_worker,
259 resource_request_.resource_type, base::nullopt,
260 net::NetLogWithSource() /* TODO(scottmg): net log? */,
261 base::Bind(&ServiceWorkerURLJobWrapper::DidPrepareFetchEvent,
262 weak_factory_.GetWeakPtr(), active_worker),
263 base::Bind(&ServiceWorkerURLJobWrapper::DidDispatchFetchEvent,
264 weak_factory_.GetWeakPtr())));
265 fetch_dispatcher_->Run();
266 }
267
268 std::unique_ptr<ServiceWorkerFetchRequest>
269 ServiceWorkerURLJobWrapper::CreateFetchRequest(const ResourceRequest& request) {
270 std::string blob_uuid;
271 uint64_t blob_size = 0;
272 // TODO(scottmg): Implement passing body as blob to handler.
273 DCHECK(!request.request_body);
274 std::unique_ptr<ServiceWorkerFetchRequest> new_request(
275 new ServiceWorkerFetchRequest());
276 new_request->mode = request.fetch_request_mode;
277 new_request->is_main_resource_load =
278 ServiceWorkerUtils::IsMainResourceType(request.resource_type);
279 new_request->request_context_type = request.fetch_request_context_type;
280 new_request->frame_type = request.fetch_frame_type;
281 new_request->url = request.url;
282 new_request->method = request.method;
283 new_request->blob_uuid = blob_uuid;
284 new_request->blob_size = blob_size;
285 new_request->credentials_mode = request.fetch_credentials_mode;
286 new_request->redirect_mode = request.fetch_redirect_mode;
287 new_request->is_reload = ui::PageTransitionCoreTypeIs(
288 request.transition_type, ui::PAGE_TRANSITION_RELOAD);
289 new_request->referrer =
290 Referrer(GURL(request.referrer), request.referrer_policy);
291 new_request->fetch_type = ServiceWorkerFetchType::FETCH;
292 return new_request;
293 }
294
295 void ServiceWorkerURLJobWrapper::DidPrepareFetchEvent(
296 scoped_refptr<ServiceWorkerVersion> version) {}
297
298 void ServiceWorkerURLJobWrapper::DidDispatchFetchEvent(
299 ServiceWorkerStatusCode status,
300 ServiceWorkerFetchEventResult fetch_result,
301 const ServiceWorkerResponse& response,
302 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
303 const scoped_refptr<ServiceWorkerVersion>& version) {
304 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
305 std::move(loader_factory_callback_).Run(nullptr);
306 return;
307 }
308 DCHECK_EQ(fetch_result, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
309
310 factory_ = base::MakeUnique<Factory>(response, std::move(body_as_stream),
311 blob_storage_context_);
312 std::move(loader_factory_callback_).Run(factory_.get());
120 } 313 }
121 314
122 } // namespace content 315 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698