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

Side by Side Diff: content/browser/service_worker/service_worker_url_loader_job.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
« no previous file with comments | « content/browser/service_worker/service_worker_url_loader_job.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/service_worker/service_worker_url_loader_job.h"
6
7 #include "base/command_line.h"
8 #include "content/browser/service_worker/service_worker_fetch_dispatcher.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"
13 #include "content/public/common/browser_side_navigation_policy.h"
14 #include "content/public/common/content_switches.h"
15 #include "net/base/io_buffer.h"
16 #include "storage/browser/blob/blob_reader.h"
17 #include "storage/browser/blob/blob_storage_context.h"
18
19 namespace content {
20
21 ServiceWorkerURLLoaderJob::ServiceWorkerURLLoaderJob(
22 LoaderCallback callback,
23 Delegate* delegate,
24 const ResourceRequest& resource_request,
25 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
26 : loader_callback_(std::move(callback)),
27 delegate_(delegate),
28 resource_request_(resource_request),
29 blob_storage_context_(blob_storage_context),
30 binding_(this),
31 weak_factory_(this) {
32 DCHECK(IsBrowserSideNavigationEnabled() &&
33 base::CommandLine::ForCurrentProcess()->HasSwitch(
34 switches::kEnableNetworkService));
35 }
36
37 ServiceWorkerURLLoaderJob::~ServiceWorkerURLLoaderJob() {}
38
39 void ServiceWorkerURLLoaderJob::FallbackToNetwork() {
40 response_type_ = FALLBACK_TO_NETWORK;
41 // This could be called multiple times in some cases because we simply
42 // call this synchronously here and don't wait for a separate async
43 // StartRequest cue like what URLRequestJob case does.
44 // TODO(kinuko): Make sure this is ok or we need to make this async.
45 if (!loader_callback_.is_null())
46 std::move(loader_callback_).Run(StartLoaderCallback());
47 }
48
49 void ServiceWorkerURLLoaderJob::FallbackToNetworkOrRenderer() {
50 // TODO(kinuko): Implement this. Now we always fallback to network.
51 FallbackToNetwork();
52 }
53
54 void ServiceWorkerURLLoaderJob::ForwardToServiceWorker() {
55 response_type_ = FORWARD_TO_SERVICE_WORKER;
56 StartRequest();
57 }
58
59 bool ServiceWorkerURLLoaderJob::ShouldFallbackToNetwork() {
60 return response_type_ == FALLBACK_TO_NETWORK;
61 }
62
63 ui::PageTransition ServiceWorkerURLLoaderJob::GetPageTransition() {
64 NOTIMPLEMENTED();
65 return ui::PAGE_TRANSITION_LINK;
66 }
67
68 size_t ServiceWorkerURLLoaderJob::GetURLChainSize() const {
69 NOTIMPLEMENTED();
70 return 0;
71 }
72
73 void ServiceWorkerURLLoaderJob::FailDueToLostController() {
74 NOTIMPLEMENTED();
75 }
76
77 void ServiceWorkerURLLoaderJob::Cancel() {
78 canceled_ = true;
79 }
80
81 bool ServiceWorkerURLLoaderJob::WasCanceled() const {
82 return canceled_;
83 }
84
85 void ServiceWorkerURLLoaderJob::StartRequest() {
86 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_);
87
88 ServiceWorkerMetrics::URLRequestJobResult result =
89 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
90 ServiceWorkerVersion* active_worker =
91 delegate_->GetServiceWorkerVersion(&result);
92
93 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
94 CreateFetchRequest(resource_request_), active_worker,
95 resource_request_.resource_type, base::nullopt,
96 net::NetLogWithSource() /* TODO(scottmg): net log? */,
97 base::Bind(&ServiceWorkerURLLoaderJob::DidPrepareFetchEvent,
98 weak_factory_.GetWeakPtr(), active_worker),
99 base::Bind(&ServiceWorkerURLLoaderJob::DidDispatchFetchEvent,
100 weak_factory_.GetWeakPtr())));
101 fetch_dispatcher_->Run();
102 }
103
104 std::unique_ptr<ServiceWorkerFetchRequest>
105 ServiceWorkerURLLoaderJob::CreateFetchRequest(const ResourceRequest& request) {
106 std::string blob_uuid;
107 uint64_t blob_size = 0;
108 // TODO(scottmg): Implement passing body as blob to handler.
109 DCHECK(!request.request_body);
110 auto new_request = base::MakeUnique<ServiceWorkerFetchRequest>();
111 new_request->mode = request.fetch_request_mode;
112 new_request->is_main_resource_load =
113 ServiceWorkerUtils::IsMainResourceType(request.resource_type);
114 new_request->request_context_type = request.fetch_request_context_type;
115 new_request->frame_type = request.fetch_frame_type;
116 new_request->url = request.url;
117 new_request->method = request.method;
118 new_request->blob_uuid = blob_uuid;
119 new_request->blob_size = blob_size;
120 new_request->credentials_mode = request.fetch_credentials_mode;
121 new_request->redirect_mode = request.fetch_redirect_mode;
122 new_request->is_reload = ui::PageTransitionCoreTypeIs(
123 request.transition_type, ui::PAGE_TRANSITION_RELOAD);
124 new_request->referrer =
125 Referrer(GURL(request.referrer), request.referrer_policy);
126 new_request->fetch_type = ServiceWorkerFetchType::FETCH;
127 return new_request;
128 }
129
130 void ServiceWorkerURLLoaderJob::DidPrepareFetchEvent(
131 scoped_refptr<ServiceWorkerVersion> version) {}
132
133 void ServiceWorkerURLLoaderJob::DidDispatchFetchEvent(
134 ServiceWorkerStatusCode status,
135 ServiceWorkerFetchEventResult fetch_result,
136 const ServiceWorkerResponse& response,
137 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
138 const scoped_refptr<ServiceWorkerVersion>& version) {
139 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
140 std::move(loader_callback_).Run(StartLoaderCallback());
141 return;
142 }
143 DCHECK_EQ(fetch_result, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE);
144 std::move(loader_callback_)
145 .Run(base::Bind(&ServiceWorkerURLLoaderJob::StartResponse,
146 weak_factory_.GetWeakPtr(), response,
147 base::Passed(std::move(body_as_stream))));
148 }
149
150 void ServiceWorkerURLLoaderJob::StartResponse(
151 const ServiceWorkerResponse& response,
152 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
153 mojom::URLLoaderRequest request,
154 mojom::URLLoaderClientPtr client) {
155 DCHECK(!binding_.is_bound());
156 binding_.Bind(std::move(request));
157 binding_.set_connection_error_handler(
158 base::Bind(&ServiceWorkerURLLoaderJob::Cancel, base::Unretained(this)));
159 url_loader_client_ = std::move(client);
160
161 ResourceResponseHead head;
162 // TODO(scottmg): More fields in |head| required?
163 head.headers = new net::HttpResponseHeaders("");
164 for (const auto& kv : response.headers)
165 head.headers->AddHeader(kv.first + ": " + kv.second);
166 head.url_list_via_service_worker = response.url_list;
167 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
168 head.was_fetched_via_service_worker = true;
169 head.cors_exposed_header_names = response.cors_exposed_header_names;
170 url_loader_client_->OnReceiveResponse(
171 head, base::nullopt /* TODO(scottmg): ssl info */,
172 mojom::DownloadedTempFilePtr());
173
174 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use
175 // this case. See:
176 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5yy Ljfld0KvKchVfA84Y/edit?usp=drive_web
177 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
178 url_loader_client_->OnStartLoadingResponseBody(
179 std::move(body_as_stream->stream));
180 } else {
181 // TODO(scottmg): This is temporary way to load the blob right here and
182 // turn it into a data pipe to respond with, until we are always able to
183 // take the above path.
184 if (!response.blob_uuid.empty() && blob_storage_context_) {
185 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
186 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
187 blob_reader_ = blob_data_handle->CreateReader(
188 nullptr /* file system context */,
189 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
190 CHECK(storage::BlobReader::Status::DONE ==
191 blob_reader_->CalculateSize(net::CompletionCallback()));
192 blob_reader_->SetReadRange(0, blob_reader_->total_size());
193 scoped_refptr<net::IOBuffer> buffer(
194 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
195
196 int bytes_read;
197 blob_reader_->Read(buffer.get(), blob_reader_->total_size(), &bytes_read,
198 base::Bind(&ServiceWorkerURLLoaderJob::AfterRead,
199 weak_factory_.GetWeakPtr(), buffer));
200 }
201 }
202 }
203
204 void ServiceWorkerURLLoaderJob::AfterRead(scoped_refptr<net::IOBuffer> buffer,
205 int bytes) {
206 uint32_t bytes_written = static_cast<uint32_t>(bytes);
207 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
208 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
209 url_loader_client_->OnStartLoadingResponseBody(
210 std::move(data_pipe_.consumer_handle));
211 }
212
213 void ServiceWorkerURLLoaderJob::FollowRedirect() {
214 NOTIMPLEMENTED();
215 }
216
217 void ServiceWorkerURLLoaderJob::SetPriority(net::RequestPriority priority,
218 int32_t intra_priority_value) {
219 NOTIMPLEMENTED();
220 }
221
222 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_url_loader_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698