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

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: 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_job_wrapper.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
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(ServiceWorkerVersion* version,
25 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
26 mojom::URLLoaderAssociatedRequest url_loader_request,
27 int32_t options,
28 const ResourceRequest& request,
29 mojom::URLLoaderClientPtr url_loader_client)
30 : blob_storage_context_(blob_storage_context),
31 options_(options),
32 binding_(this, std::move(url_loader_request)),
33 url_loader_client_(std::move(url_loader_client)),
34 weak_factory_(this) {
35 if (options_ & mojom::kURLLoadOptionSendSSLInfo) {
36 // TODO(scottmg): User ssl_info() here.
37 }
38 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
39 CreateFetchRequest(request), version, request.resource_type,
40 base::nullopt, net::NetLogWithSource() /* TODO(scottmg): net log? */,
41 base::Bind(&URLLoaderImpl::DidPrepareFetchEvent,
42 weak_factory_.GetWeakPtr(), version),
43 base::Bind(&URLLoaderImpl::DidDispatchFetchEvent,
44 weak_factory_.GetWeakPtr())));
45 fetch_dispatcher_->Run();
46 }
47
48 // mojom::URLLoader:
49 void FollowRedirect() override { NOTIMPLEMENTED(); }
50
51 void SetPriority(net::RequestPriority priority,
52 int32_t intra_priority_value) override {
53 NOTIMPLEMENTED();
54 }
55
56 private:
57 std::unique_ptr<ServiceWorkerFetchRequest> CreateFetchRequest(
58 const ResourceRequest& request) {
59 std::string blob_uuid;
60 uint64_t blob_size = 0;
61 #if 0 // TODO(scottmg):
62 if (HasRequestBody())
63 CreateRequestBodyBlob(&blob_uuid, &blob_size);
64 #endif
65 std::unique_ptr<ServiceWorkerFetchRequest> new_request(
66 new ServiceWorkerFetchRequest());
67 new_request->mode = request.fetch_request_mode;
68 new_request->is_main_resource_load =
69 ServiceWorkerUtils::IsMainResourceType(request.resource_type);
70 new_request->request_context_type = request.fetch_request_context_type;
71 new_request->frame_type = request.fetch_frame_type;
72 new_request->url = request.url;
73 new_request->method = request.method;
74 #if 0 // TODO(scottmg):
75 const net::HttpRequestHeaders& headers = request_->extra_request_headers();
76 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
77 if (ServiceWorkerContext::IsExcludedHeaderNameForFetchEvent(it.name()))
78 continue;
79 new_request->headers[it.name()] = it.value();
80 }
81 #endif
82 new_request->blob_uuid = blob_uuid;
83 new_request->blob_size = blob_size;
84 new_request->credentials_mode = request.fetch_credentials_mode;
85 new_request->redirect_mode = request.fetch_redirect_mode;
86 #if 0 // TODO(scottmg):
87 new_request->client_id = client_id_;
88 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
89 if (info) {
90 new_request->is_reload = ui::PageTransitionCoreTypeIs(
91 info->GetPageTransition(), ui::PAGE_TRANSITION_RELOAD);
92 new_request->referrer =
93 Referrer(GURL(request_->referrer()), info->GetReferrerPolicy());
94 } else {
95 CHECK(
96 request_->referrer_policy() ==
97 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE) ;
98 new_request->referrer =
99 Referrer(GURL(request_->referrer()), blink::kWebReferrerPolicyDefault) ;
100 }
101 new_request->fetch_type = fetch_type_;
102 #endif
103 return new_request;
104 }
105
106 void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version) {}
107
108 void DidDispatchFetchEvent(
109 ServiceWorkerStatusCode status,
110 ServiceWorkerFetchEventResult fetch_result,
shimazu 2017/05/31 01:48:00 If the |fetch_result| is SERVICE_WORKER_FETCH_EVEN
111 const ServiceWorkerResponse& response,
112 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
113 const scoped_refptr<ServiceWorkerVersion>& version) {
114 ResourceResponseHead head;
115 // TODO(scottmg): More fields in |head| required.
116 head.headers = new net::HttpResponseHeaders("");
117 for (const auto& kv : response.headers)
118 head.headers->AddHeader(kv.first + ": " + kv.second);
119 head.url_list_via_service_worker = response.url_list;
120 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
121 head.was_fetched_via_service_worker = true;
122 head.cors_exposed_header_names = response.cors_exposed_header_names;
123 url_loader_client_->OnReceiveResponse(
124 head, base::nullopt /* TODO(scottmg): ssl info */,
125 mojom::DownloadedTempFilePtr());
126
127 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use
128 // this case. See:
129 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5 yyLjfld0KvKchVfA84Y/edit?usp=drive_web
130 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
131 url_loader_client_->OnStartLoadingResponseBody(
132 std::move(body_as_stream->stream));
shimazu 2017/05/30 08:32:00 If loading the body gets aborted, how the error wi
133 } else {
134 // TODO(scottmg): This is temporary way to load the blob right here and
135 // turn it into a data pipe to respond with, until we are always able to
136 // take the above path.
137 if (!response.blob_uuid.empty() && blob_storage_context_) {
138 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
139 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
140 blob_reader_ = blob_data_handle->CreateReader(
141 nullptr /* file system context */,
142 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
143 CHECK(storage::BlobReader::Status::DONE ==
144 blob_reader_->CalculateSize(net::CompletionCallback()));
145 blob_reader_->SetReadRange(0, blob_reader_->total_size());
146 scoped_refptr<net::IOBuffer> buffer(
147 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
148
149 int bytes_read;
150 blob_reader_->Read(buffer.get(), blob_reader_->total_size(),
151 &bytes_read,
152 base::Bind(&URLLoaderImpl::AfterRead,
153 weak_factory_.GetWeakPtr(), buffer));
154 }
155 }
156 }
157
158 void AfterRead(scoped_refptr<net::IOBuffer> buffer, int bytes) {
159 uint32_t bytes_written = static_cast<uint32_t>(bytes);
160 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
161 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
162 url_loader_client_->OnStartLoadingResponseBody(
163 std::move(data_pipe_.consumer_handle));
164 }
165
166 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
167 int32_t options_;
168 mojo::AssociatedBinding<mojom::URLLoader> binding_;
169 mojom::URLLoaderClientPtr url_loader_client_;
170 std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
171 std::unique_ptr<storage::BlobReader> blob_reader_;
172 mojo::DataPipe data_pipe_;
173
174 base::WeakPtrFactory<URLLoaderImpl> weak_factory_;
175
176 DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
177 };
178
179 } // namespace
180
181 class ServiceWorkerURLJobWrapper::Factory : public mojom::URLLoaderFactory {
182 public:
183 Factory(ServiceWorkerURLJobWrapper::Delegate* delegate,
184 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
185 : delegate_(delegate), blob_storage_context_(blob_storage_context) {}
186
187 void CreateLoaderAndStart(mojom::URLLoaderAssociatedRequest request,
188 int32_t routing_id,
189 int32_t request_id,
190 uint32_t options,
191 const ResourceRequest& url_request,
192 mojom::URLLoaderClientPtr client) override {
193 ServiceWorkerMetrics::URLRequestJobResult result =
194 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
195 ServiceWorkerVersion* active_worker =
196 delegate_->GetServiceWorkerVersion(&result);
197 new URLLoaderImpl(active_worker, blob_storage_context_, std::move(request),
198 options, url_request, std::move(client));
199 }
200
201 void SyncLoad(int32_t routing_id,
202 int32_t request_id,
203 const ResourceRequest& url_request,
204 SyncLoadCallback callback) override {
205 NOTREACHED();
206 }
207
208 private:
209 ServiceWorkerURLJobWrapper::Delegate* delegate_;
210 base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
211
212 DISALLOW_COPY_AND_ASSIGN(Factory);
213 };
214
15 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper( 215 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
16 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job) 216 base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job)
17 : job_type_(JobType::kURLRequest), 217 : job_type_(JobType::kURLRequest),
18 url_request_job_(std::move(url_request_job)), 218 url_request_job_(std::move(url_request_job)),
19 weak_factory_(this) {} 219 weak_factory_(this) {}
20 220
21 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper( 221 ServiceWorkerURLJobWrapper::ServiceWorkerURLJobWrapper(
22 LoaderFactoryCallback callback) 222 LoaderFactoryCallback callback,
223 Delegate* delegate,
224 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
23 : job_type_(JobType::kURLLoader), 225 : job_type_(JobType::kURLLoader),
24 loader_factory_callback_(std::move(callback)), 226 loader_factory_callback_(std::move(callback)),
227 delegate_(delegate),
228 blob_storage_context_(blob_storage_context),
25 weak_factory_(this) { 229 weak_factory_(this) {
26 DCHECK(IsBrowserSideNavigationEnabled() && 230 DCHECK(IsBrowserSideNavigationEnabled() &&
27 base::CommandLine::ForCurrentProcess()->HasSwitch( 231 base::CommandLine::ForCurrentProcess()->HasSwitch(
28 switches::kEnableNetworkService)); 232 switches::kEnableNetworkService));
29 } 233 }
30 234
31 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {} 235 ServiceWorkerURLJobWrapper::~ServiceWorkerURLJobWrapper() {}
32 236
33 void ServiceWorkerURLJobWrapper::FallbackToNetwork() { 237 void ServiceWorkerURLJobWrapper::FallbackToNetwork() {
34 if (job_type_ == JobType::kURLLoader) { 238 if (job_type_ == JobType::kURLLoader) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 bool ServiceWorkerURLJobWrapper::WasCanceled() const { 309 bool ServiceWorkerURLJobWrapper::WasCanceled() const {
106 if (job_type_ == JobType::kURLLoader) { 310 if (job_type_ == JobType::kURLLoader) {
107 return loader_factory_callback_.is_null(); 311 return loader_factory_callback_.is_null();
108 } else { 312 } else {
109 return !url_request_job_; 313 return !url_request_job_;
110 } 314 }
111 } 315 }
112 316
113 void ServiceWorkerURLJobWrapper::StartRequest() { 317 void ServiceWorkerURLJobWrapper::StartRequest() {
114 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_); 318 DCHECK_EQ(FORWARD_TO_SERVICE_WORKER, response_type_);
115 // TODO(kinuko): Implement. For now we just exercise async fall back path 319 factory_ = base::MakeUnique<Factory>(delegate_, blob_storage_context_);
kinuko 2017/05/29 14:30:48 I think we can delay creating the factory and URLL
shimazu 2017/05/30 08:32:00 +1 for deferring because currently the network req
scottmg 2017/05/30 18:07:48 Sorry, maybe I'm misunderstanding, but I think we
shimazu 2017/05/31 01:48:00 Ah, I missed that.. sorry! We need the ResourceReq
kinuko 2017/05/31 02:03:43 We can pass the info when we create a job. Either
116 // to the network. 320 std::move(loader_factory_callback_).Run(factory_.get());
117 base::ThreadTaskRunnerHandle::Get()->PostTask(
118 FROM_HERE, base::Bind(&ServiceWorkerURLJobWrapper::FallbackToNetwork,
119 weak_factory_.GetWeakPtr()));
120 } 321 }
121 322
122 } // namespace content 323 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_url_job_wrapper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698