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

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: rebase and fix debug component 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 "net/base/io_buffer.h"
16 #include "storage/browser/blob/blob_storage_context.h"
12 17
13 namespace content { 18 namespace content {
14 19
20 namespace {
21
22 class URLLoaderImpl : public mojom::URLLoader {
23 public:
24 URLLoaderImpl(const ServiceWorkerResponse& response,
25 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
26 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
27 mojom::URLLoaderAssociatedRequest url_loader_request,
28 mojom::URLLoaderClientPtr url_loader_client)
29 : blob_storage_context_(blob_storage_context),
30 binding_(this, std::move(url_loader_request)),
31 url_loader_client_(std::move(url_loader_client)),
32 weak_factory_(this) {
33 ResourceResponseHead head;
34 // TODO(scottmg): More fields in |head| required?
35 head.headers = new net::HttpResponseHeaders("");
36 for (const auto& kv : response.headers)
37 head.headers->AddHeader(kv.first + ": " + kv.second);
38 head.url_list_via_service_worker = response.url_list;
39 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
40 head.was_fetched_via_service_worker = true;
41 head.cors_exposed_header_names = response.cors_exposed_header_names;
42 url_loader_client_->OnReceiveResponse(
43 head, base::nullopt /* TODO(scottmg): ssl info */,
44 mojom::DownloadedTempFilePtr());
45
46 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use
47 // this case. See:
48 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5 yyLjfld0KvKchVfA84Y/edit?usp=drive_web
49 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
50 url_loader_client_->OnStartLoadingResponseBody(
51 std::move(body_as_stream->stream));
52 } else {
53 // TODO(scottmg): This is temporary way to load the blob right here and
54 // turn it into a data pipe to respond with, until we are always able to
55 // take the above path.
56 if (!response.blob_uuid.empty() && blob_storage_context_) {
57 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
58 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
59 blob_reader_ = blob_data_handle->CreateReader(
60 nullptr /* file system context */,
61 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
62 CHECK(storage::BlobReader::Status::DONE ==
63 blob_reader_->CalculateSize(net::CompletionCallback()));
64 blob_reader_->SetReadRange(0, blob_reader_->total_size());
65 scoped_refptr<net::IOBuffer> buffer(
66 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
67
68 int bytes_read;
69 blob_reader_->Read(buffer.get(), blob_reader_->total_size(),
70 &bytes_read,
71 base::Bind(&URLLoaderImpl::AfterRead,
72 weak_factory_.GetWeakPtr(), buffer));
73 }
74 }
75 }
76
77 // mojom::URLLoader:
78 void FollowRedirect() override { NOTIMPLEMENTED(); }
79
80 void SetPriority(net::RequestPriority priority,
81 int32_t intra_priority_value) override {
82 NOTIMPLEMENTED();
83 }
84
85 private:
86 void AfterRead(scoped_refptr<net::IOBuffer> buffer, int bytes) {
87 uint32_t bytes_written = static_cast<uint32_t>(bytes);
88 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
89 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
90 url_loader_client_->OnStartLoadingResponseBody(
91 std::move(data_pipe_.consumer_handle));
92 }
93
94 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
95 mojo::AssociatedBinding<mojom::URLLoader> binding_;
96 mojom::URLLoaderClientPtr url_loader_client_;
97 std::unique_ptr<storage::BlobReader> blob_reader_;
98 mojo::DataPipe data_pipe_;
99
100 base::WeakPtrFactory<URLLoaderImpl> weak_factory_;
101
102 DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
103 };
104
105 } // namespace
106
107 class ServiceWorkerURLJobWrapper::Factory : public mojom::URLLoaderFactory {
108 public:
109 Factory(const ServiceWorkerResponse& response,
110 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
111 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
112 : response_(response),
113 body_as_stream_(std::move(body_as_stream)),
114 blob_storage_context_(blob_storage_context) {}
115
116 void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest request,
117 int32_t routing_id,
118 int32_t request_id,
119 uint32_t options,
120 const ResourceRequest& url_request,
121 mojom::URLLoaderClientPtr client) override {
122 // Note that url_request is ignored here, as we've already processed the
123 // fetch before even creating the factory.
124 // TODO(scottmg): Use options.
125 new URLLoaderImpl(response_, std::move(body_as_stream_),
shimazu 2017/06/06 01:33:30 If the lifecycle of URLLoaderImpl is the same with
scottmg 2017/06/06 16:50:09 Done.
126 blob_storage_context_, std::move(request),
127 std::move(client));
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 // TODO(scottmg): Get this from somewhere, and maybe it should probably be set
258 // elsewhere too.
259 net::HttpResponseInfo http_info;
260 http_info.was_cached = true;
261 active_worker->SetMainScriptHttpResponseInfo(http_info);
kinuko 2017/06/06 12:52:37 Do we need this? (Esp. with the change in Service
falken 2017/06/06 13:20:22 Good point. I think quite a few things might break
scottmg 2017/06/06 16:50:09 OK, removed for now.
262
263 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
264 CreateFetchRequest(resource_request_), active_worker,
265 resource_request_.resource_type, base::nullopt,
266 net::NetLogWithSource() /* TODO(scottmg): net log? */,
267 base::Bind(&ServiceWorkerURLJobWrapper::DidPrepareFetchEvent,
268 weak_factory_.GetWeakPtr(), active_worker),
269 base::Bind(&ServiceWorkerURLJobWrapper::DidDispatchFetchEvent,
270 weak_factory_.GetWeakPtr())));
271 fetch_dispatcher_->Run();
272 }
273
274 std::unique_ptr<ServiceWorkerFetchRequest>
275 ServiceWorkerURLJobWrapper::CreateFetchRequest(const ResourceRequest& request) {
276 std::string blob_uuid;
277 uint64_t blob_size = 0;
278 // TODO(scottmg): Implement passing body as blob to handler.
279 DCHECK(!request.request_body);
280 std::unique_ptr<ServiceWorkerFetchRequest> new_request(
281 new ServiceWorkerFetchRequest());
282 new_request->mode = request.fetch_request_mode;
283 new_request->is_main_resource_load =
284 ServiceWorkerUtils::IsMainResourceType(request.resource_type);
285 new_request->request_context_type = request.fetch_request_context_type;
286 new_request->frame_type = request.fetch_frame_type;
287 new_request->url = request.url;
288 new_request->method = request.method;
289 new_request->blob_uuid = blob_uuid;
290 new_request->blob_size = blob_size;
291 new_request->credentials_mode = request.fetch_credentials_mode;
292 new_request->redirect_mode = request.fetch_redirect_mode;
293 CHECK(request.referrer_policy ==
294 blink::kWebReferrerPolicyNoReferrerWhenDowngrade);
295 new_request->referrer =
296 Referrer(GURL(request.referrer), blink::kWebReferrerPolicyDefault);
falken 2017/06/06 13:20:22 Why is line 293 a CHECK instead of DCHECK and line
scottmg 2017/06/06 16:50:09 Oops, yeah. I copied the fallback case from Servic
297 new_request->fetch_type = ServiceWorkerFetchType::FETCH;
298 return new_request;
299 }
300
301 void ServiceWorkerURLJobWrapper::DidPrepareFetchEvent(
302 scoped_refptr<ServiceWorkerVersion> version) {}
303
304 void ServiceWorkerURLJobWrapper::DidDispatchFetchEvent(
305 ServiceWorkerStatusCode status,
306 ServiceWorkerFetchEventResult fetch_result,
307 const ServiceWorkerResponse& response,
308 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
309 const scoped_refptr<ServiceWorkerVersion>& version) {
310 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
311 std::move(loader_factory_callback_).Run(nullptr);
312 return;
313 }
314 DCHECK_EQ(fetch_result, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
315
316 factory_ = base::MakeUnique<Factory>(response, std::move(body_as_stream),
317 blob_storage_context_);
318 std::move(loader_factory_callback_).Run(factory_.get());
120 } 319 }
121 320
122 } // namespace content 321 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698