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

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

Issue 2923413003: Split ServiceWorkerURLLoaderJob from URLJobWrapper (Closed)
Patch Set: rebase 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 "content/browser/service_worker/service_worker_url_loader_job.h"
8 #include "content/browser/service_worker/service_worker_response_type.h" 8 #include "content/browser/service_worker/service_worker_url_request_job.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"
12 #include "content/public/browser/resource_request_info.h" 9 #include "content/public/browser/resource_request_info.h"
13 #include "content/public/common/browser_side_navigation_policy.h"
14 #include "content/public/common/content_switches.h" 10 #include "content/public/common/content_switches.h"
15 #include "mojo/public/cpp/bindings/strong_binding.h"
16 #include "net/base/io_buffer.h"
17 #include "storage/browser/blob/blob_storage_context.h"
18 11
19 namespace content { 12 namespace content {
20 13
21 namespace { 14 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
22 15 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job)
23 class URLLoaderImpl : public mojom::URLLoader { 16 : url_request_job_(std::move(url_request_job)) {}
24 public:
25 static void Start(
26 const ServiceWorkerResponse& response,
27 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
28 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
29 mojom::URLLoaderRequest request,
30 mojom::URLLoaderClientPtr client) {
31 mojo::MakeStrongBinding(base::MakeUnique<URLLoaderImpl>(
32 response, std::move(body_as_stream),
33 blob_storage_context, std::move(client)),
34 std::move(request));
35 }
36
37 URLLoaderImpl(const ServiceWorkerResponse& response,
38 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
39 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
40 mojom::URLLoaderClientPtr url_loader_client)
41 : blob_storage_context_(blob_storage_context),
42 url_loader_client_(std::move(url_loader_client)),
43 weak_factory_(this) {
44 ResourceResponseHead head;
45 // TODO(scottmg): More fields in |head| required?
46 head.headers = new net::HttpResponseHeaders("");
47 for (const auto& kv : response.headers)
48 head.headers->AddHeader(kv.first + ": " + kv.second);
49 head.url_list_via_service_worker = response.url_list;
50 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
51 head.was_fetched_via_service_worker = true;
52 head.cors_exposed_header_names = response.cors_exposed_header_names;
53 url_loader_client_->OnReceiveResponse(
54 head, base::nullopt /* TODO(scottmg): ssl info */,
55 mojom::DownloadedTempFilePtr());
56
57 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use
58 // this case. See:
59 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5 yyLjfld0KvKchVfA84Y/edit?usp=drive_web
60 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
61 url_loader_client_->OnStartLoadingResponseBody(
62 std::move(body_as_stream->stream));
63 } else {
64 // TODO(scottmg): This is temporary way to load the blob right here and
65 // turn it into a data pipe to respond with, until we are always able to
66 // take the above path.
67 if (!response.blob_uuid.empty() && blob_storage_context_) {
68 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
69 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
70 blob_reader_ = blob_data_handle->CreateReader(
71 nullptr /* file system context */,
72 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
73 CHECK(storage::BlobReader::Status::DONE ==
74 blob_reader_->CalculateSize(net::CompletionCallback()));
75 blob_reader_->SetReadRange(0, blob_reader_->total_size());
76 scoped_refptr<net::IOBuffer> buffer(
77 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
78
79 int bytes_read;
80 blob_reader_->Read(buffer.get(), blob_reader_->total_size(),
81 &bytes_read,
82 base::Bind(&URLLoaderImpl::AfterRead,
83 weak_factory_.GetWeakPtr(), buffer));
84 }
85 }
86 }
87
88 // mojom::URLLoader:
89 void FollowRedirect() override { NOTIMPLEMENTED(); }
90
91 void SetPriority(net::RequestPriority priority,
92 int32_t intra_priority_value) override {
93 NOTIMPLEMENTED();
94 }
95
96 private:
97 void AfterRead(scoped_refptr<net::IOBuffer> buffer, int bytes) {
98 uint32_t bytes_written = static_cast<uint32_t>(bytes);
99 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
100 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
101 url_loader_client_->OnStartLoadingResponseBody(
102 std::move(data_pipe_.consumer_handle));
103 }
104
105 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
106 mojom::URLLoaderClientPtr url_loader_client_;
107 std::unique_ptr<storage::BlobReader> blob_reader_;
108 mojo::DataPipe data_pipe_;
109
110 base::WeakPtrFactory<URLLoaderImpl> weak_factory_;
111
112 DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
113 };
114
115 } // namespace
116 17
117 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper( 18 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
118 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job) 19 std::unique_ptr<ServiceWorkerURLLoaderJob> url_loader_job)
119 : job_type_(JobType::kURLRequest), 20 : url_loader_job_(std::move(url_loader_job)) {}
120 url_request_job_(std::move(url_request_job)),
121 weak_factory_(this) {}
122
123 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
124 LoaderCallback callback,
125 Delegate* delegate,
126 const ResourceRequest& resource_request,
127 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
128 : job_type_(JobType::kURLLoader),
129 loader_callback_(std::move(callback)),
130 delegate_(delegate),
131 resource_request_(resource_request),
132 blob_storage_context_(blob_storage_context),
133 weak_factory_(this) {
134 DCHECK(IsBrowserSideNavigationEnabled() &&
135 base::CommandLine::ForCurrentProcess()->HasSwitch(
136 switches::kEnableNetworkService));
137 }
138 21
139 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {} 22 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {}
140 23
141 void ServiceWorkerURLJobWrapper::FallbackToNetwork() { 24 void ServiceWorkerURLJobWrapper::FallbackToNetwork() {
142 if (job_type_ == JobType::kURLLoader) { 25 if (url_loader_job_) {
143 response_type_ = FALLBACK_TO_NETWORK; 26 url_loader_job_->FallbackToNetwork();
144 // This could be called multiple times in some cases because we simply
145 // call this synchronously here and don't wait for a separate async
146 // StartRequest cue like what URLRequestJob case does.
147 // TODO(kinuko): Make sure this is ok or we need to make this async.
148 if (!loader_callback_.is_null()) {
149 std::move(loader_callback_).Run(StartLoaderCallback());
150 }
151 } else { 27 } else {
152 url_request_job_->FallbackToNetwork(); 28 url_request_job_->FallbackToNetwork();
153 } 29 }
154 } 30 }
155 31
156 void ServiceWorkerURLJobWrapper::FallbackToNetworkOrRenderer() { 32 void ServiceWorkerURLJobWrapper::FallbackToNetworkOrRenderer() {
157 if (job_type_ == JobType::kURLLoader) { 33 if (url_loader_job_) {
158 // TODO(kinuko): Implement this. Now we always fallback to network. 34 url_loader_job_->FallbackToNetworkOrRenderer();
159 FallbackToNetwork();
160 } else { 35 } else {
161 url_request_job_->FallbackToNetworkOrRenderer(); 36 url_request_job_->FallbackToNetworkOrRenderer();
162 } 37 }
163 } 38 }
164 39
165 void ServiceWorkerURLJobWrapper::ForwardToServiceWorker() { 40 void ServiceWorkerURLJobWrapper::ForwardToServiceWorker() {
166 if (job_type_ == JobType::kURLLoader) { 41 if (url_loader_job_) {
167 response_type_ = FORWARD_TO_SERVICE_WORKER; 42 url_loader_job_->ForwardToServiceWorker();
168 StartRequest();
169 } else { 43 } else {
170 url_request_job_->ForwardToServiceWorker(); 44 url_request_job_->ForwardToServiceWorker();
171 } 45 }
172 } 46 }
173 47
174 bool ServiceWorkerURLJobWrapper::ShouldFallbackToNetwork() { 48 bool ServiceWorkerURLJobWrapper::ShouldFallbackToNetwork() {
175 if (job_type_ == JobType::kURLLoader) { 49 if (url_loader_job_) {
176 return response_type_ == FALLBACK_TO_NETWORK; 50 return url_loader_job_->ShouldFallbackToNetwork();
177 } else { 51 } else {
178 return url_request_job_->ShouldFallbackToNetwork(); 52 return url_request_job_->ShouldFallbackToNetwork();
179 } 53 }
180 } 54 }
181 55
182 ui::PageTransition ServiceWorkerURLJobWrapper::GetPageTransition() { 56 ui::PageTransition ServiceWorkerURLJobWrapper::GetPageTransition() {
183 if (job_type_ == JobType::kURLLoader) { 57 if (url_loader_job_) {
184 NOTIMPLEMENTED(); 58 return url_loader_job_->GetPageTransition();
185 return ui::PAGE_TRANSITION_LINK;
186 } else { 59 } else {
187 const ResourceRequestInfo* info = 60 const ResourceRequestInfo* info =
188 ResourceRequestInfo::ForRequest(url_request_job_->request()); 61 ResourceRequestInfo::ForRequest(url_request_job_->request());
189 // ResourceRequestInfo may not be set in some tests. 62 // ResourceRequestInfo may not be set in some tests.
190 if (!info) 63 if (!info)
191 return ui::PAGE_TRANSITION_LINK; 64 return ui::PAGE_TRANSITION_LINK;
192 return info->GetPageTransition(); 65 return info->GetPageTransition();
193 } 66 }
194 } 67 }
195 68
196 size_t ServiceWorkerURLJobWrapper::GetURLChainSize() const { 69 size_t ServiceWorkerURLJobWrapper::GetURLChainSize() const {
197 if (job_type_ == JobType::kURLLoader) { 70 if (url_loader_job_) {
198 NOTIMPLEMENTED(); 71 return url_loader_job_->GetURLChainSize();
199 return 0;
200 } else { 72 } else {
201 return url_request_job_->request()->url_chain().size(); 73 return url_request_job_->request()->url_chain().size();
202 } 74 }
203 } 75 }
204 76
205 void ServiceWorkerURLJobWrapper::FailDueToLostController() { 77 void ServiceWorkerURLJobWrapper::FailDueToLostController() {
206 if (job_type_ == JobType::kURLLoader) { 78 if (url_loader_job_) {
207 NOTIMPLEMENTED(); 79 url_loader_job_->FailDueToLostController();
208 } else { 80 } else {
209 url_request_job_->FailDueToLostController(); 81 url_request_job_->FailDueToLostController();
210 } 82 }
211 } 83 }
212 84
213 bool ServiceWorkerURLJobWrapper::WasCanceled() const { 85 bool ServiceWorkerURLJobWrapper::WasCanceled() const {
214 if (job_type_ == JobType::kURLLoader) { 86 if (url_loader_job_) {
215 return loader_callback_.is_null(); 87 return url_loader_job_->WasCanceled();
216 } else { 88 } else {
217 return !url_request_job_; 89 return !url_request_job_;
218 } 90 }
219 } 91 }
220 92
221 void ServiceWorkerURLJobWrapper::StartRequest() {
222 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_);
223
224 ServiceWorkerMetrics::URLRequestJobResult result =
225 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
226 ServiceWorkerVersion* active_worker =
227 delegate_->GetServiceWorkerVersion(&result);
228
229 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
230 CreateFetchRequest(resource_request_), active_worker,
231 resource_request_.resource_type, base::nullopt,
232 net::NetLogWithSource() /* TODO(scottmg): net log? */,
233 base::Bind(&ServiceWorkerURLJobWrapper::DidPrepareFetchEvent,
234 weak_factory_.GetWeakPtr(), active_worker),
235 base::Bind(&ServiceWorkerURLJobWrapper::DidDispatchFetchEvent,
236 weak_factory_.GetWeakPtr())));
237 fetch_dispatcher_->Run();
238 }
239
240 std::unique_ptr<ServiceWorkerFetchRequest>
241 ServiceWorkerURLJobWrapper::CreateFetchRequest(const ResourceRequest& request) {
242 std::string blob_uuid;
243 uint64_t blob_size = 0;
244 // TODO(scottmg): Implement passing body as blob to handler.
245 DCHECK(!request.request_body);
246 std::unique_ptr<ServiceWorkerFetchRequest> new_request(
247 new ServiceWorkerFetchRequest());
248 new_request->mode = request.fetch_request_mode;
249 new_request->is_main_resource_load =
250 ServiceWorkerUtils::IsMainResourceType(request.resource_type);
251 new_request->request_context_type = request.fetch_request_context_type;
252 new_request->frame_type = request.fetch_frame_type;
253 new_request->url = request.url;
254 new_request->method = request.method;
255 new_request->blob_uuid = blob_uuid;
256 new_request->blob_size = blob_size;
257 new_request->credentials_mode = request.fetch_credentials_mode;
258 new_request->redirect_mode = request.fetch_redirect_mode;
259 new_request->is_reload = ui::PageTransitionCoreTypeIs(
260 request.transition_type, ui::PAGE_TRANSITION_RELOAD);
261 new_request->referrer =
262 Referrer(GURL(request.referrer), request.referrer_policy);
263 new_request->fetch_type = ServiceWorkerFetchType::FETCH;
264 return new_request;
265 }
266
267 void ServiceWorkerURLJobWrapper::DidPrepareFetchEvent(
268 scoped_refptr<ServiceWorkerVersion> version) {}
269
270 void ServiceWorkerURLJobWrapper::DidDispatchFetchEvent(
271 ServiceWorkerStatusCode status,
272 ServiceWorkerFetchEventResult fetch_result,
273 const ServiceWorkerResponse& response,
274 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
275 const scoped_refptr<ServiceWorkerVersion>& version) {
276 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
277 std::move(loader_callback_).Run(StartLoaderCallback());
278 return;
279 }
280 DCHECK_EQ(fetch_result, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
281 std::move(loader_callback_)
282 .Run(base::Bind(&URLLoaderImpl::Start, response,
283 base::Passed(std::move(body_as_stream)),
284 blob_storage_context_));
285 }
286
287 } // namespace content 93 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698