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

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

Issue 759203002: [ServiceWorker] Make Stream support in ServiceWorkerURLRequestJob (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: incorporated tyoshino and nhiroki's comment Created 6 years 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_request_job.h" 5 #include "content/browser/service_worker/service_worker_url_request_job.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/guid.h" 12 #include "base/guid.h"
13 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "content/browser/resource_context_impl.h"
16 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 17 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
17 #include "content/browser/service_worker/service_worker_provider_host.h" 18 #include "content/browser/service_worker/service_worker_provider_host.h"
19 #include "content/browser/streams/stream.h"
20 #include "content/browser/streams/stream_context.h"
21 #include "content/browser/streams/stream_registry.h"
18 #include "content/common/resource_request_body.h" 22 #include "content/common/resource_request_body.h"
19 #include "content/common/service_worker/service_worker_types.h" 23 #include "content/common/service_worker/service_worker_types.h"
20 #include "content/public/browser/blob_handle.h" 24 #include "content/public/browser/blob_handle.h"
21 #include "content/public/browser/resource_request_info.h" 25 #include "content/public/browser/resource_request_info.h"
22 #include "content/public/browser/service_worker_context.h" 26 #include "content/public/browser/service_worker_context.h"
23 #include "net/base/net_errors.h" 27 #include "net/base/net_errors.h"
24 #include "net/http/http_request_headers.h" 28 #include "net/http/http_request_headers.h"
25 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
26 #include "net/http/http_response_info.h" 30 #include "net/http/http_response_info.h"
27 #include "net/http/http_util.h" 31 #include "net/http/http_util.h"
28 #include "storage/browser/blob/blob_data_handle.h" 32 #include "storage/browser/blob/blob_data_handle.h"
29 #include "storage/browser/blob/blob_storage_context.h" 33 #include "storage/browser/blob/blob_storage_context.h"
30 #include "storage/browser/blob/blob_url_request_job_factory.h" 34 #include "storage/browser/blob/blob_url_request_job_factory.h"
31 #include "ui/base/page_transition_types.h" 35 #include "ui/base/page_transition_types.h"
32 36
33 namespace content { 37 namespace content {
34 38
35 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( 39 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
36 net::URLRequest* request, 40 net::URLRequest* request,
37 net::NetworkDelegate* network_delegate, 41 net::NetworkDelegate* network_delegate,
38 base::WeakPtr<ServiceWorkerProviderHost> provider_host, 42 base::WeakPtr<ServiceWorkerProviderHost> provider_host,
39 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, 43 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
44 const ResourceContext* resource_context,
40 FetchRequestMode request_mode, 45 FetchRequestMode request_mode,
41 FetchCredentialsMode credentials_mode, 46 FetchCredentialsMode credentials_mode,
42 RequestContextType request_context_type, 47 RequestContextType request_context_type,
43 RequestContextFrameType frame_type, 48 RequestContextFrameType frame_type,
44 scoped_refptr<ResourceRequestBody> body) 49 scoped_refptr<ResourceRequestBody> body)
45 : net::URLRequestJob(request, network_delegate), 50 : net::URLRequestJob(request, network_delegate),
46 provider_host_(provider_host), 51 provider_host_(provider_host),
47 response_type_(NOT_DETERMINED), 52 response_type_(NOT_DETERMINED),
48 is_started_(false), 53 is_started_(false),
49 service_worker_response_type_(blink::WebServiceWorkerResponseTypeDefault), 54 service_worker_response_type_(blink::WebServiceWorkerResponseTypeDefault),
50 blob_storage_context_(blob_storage_context), 55 blob_storage_context_(blob_storage_context),
56 resource_context_(resource_context),
57 stream_pending_buffer_size_(0),
51 request_mode_(request_mode), 58 request_mode_(request_mode),
52 credentials_mode_(credentials_mode), 59 credentials_mode_(credentials_mode),
53 request_context_type_(request_context_type), 60 request_context_type_(request_context_type),
54 frame_type_(frame_type), 61 frame_type_(frame_type),
55 fall_back_required_(false), 62 fall_back_required_(false),
56 body_(body), 63 body_(body),
57 weak_factory_(this) { 64 weak_factory_(this) {
58 } 65 }
59 66
60 void ServiceWorkerURLRequestJob::FallbackToNetwork() { 67 void ServiceWorkerURLRequestJob::FallbackToNetwork() {
61 DCHECK_EQ(NOT_DETERMINED, response_type_); 68 DCHECK_EQ(NOT_DETERMINED, response_type_);
62 response_type_ = FALLBACK_TO_NETWORK; 69 response_type_ = FALLBACK_TO_NETWORK;
63 MaybeStartRequest(); 70 MaybeStartRequest();
64 } 71 }
65 72
66 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { 73 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
67 DCHECK_EQ(NOT_DETERMINED, response_type_); 74 DCHECK_EQ(NOT_DETERMINED, response_type_);
68 response_type_ = FORWARD_TO_SERVICE_WORKER; 75 response_type_ = FORWARD_TO_SERVICE_WORKER;
69 MaybeStartRequest(); 76 MaybeStartRequest();
70 } 77 }
71 78
72 void ServiceWorkerURLRequestJob::Start() { 79 void ServiceWorkerURLRequestJob::Start() {
73 is_started_ = true; 80 is_started_ = true;
74 MaybeStartRequest(); 81 MaybeStartRequest();
75 } 82 }
76 83
77 void ServiceWorkerURLRequestJob::Kill() { 84 void ServiceWorkerURLRequestJob::Kill() {
78 net::URLRequestJob::Kill(); 85 net::URLRequestJob::Kill();
86 if (stream_) {
87 stream_->RemoveReadObserver(this);
88 stream_->Abort();
89 stream_ = nullptr;
90 }
91 if (!waiting_stream_url_.is_empty()) {
92 StreamRegistry* stream_registry =
93 GetStreamContextForResourceContext(resource_context_)->registry();
94 stream_registry->RemoveRegisterObserver(waiting_stream_url_);
95 stream_registry->NotifyReaderAbortedBeforeRegistration(waiting_stream_url_);
96 }
79 fetch_dispatcher_.reset(); 97 fetch_dispatcher_.reset();
80 blob_request_.reset(); 98 blob_request_.reset();
81 weak_factory_.InvalidateWeakPtrs(); 99 weak_factory_.InvalidateWeakPtrs();
82 } 100 }
83 101
84 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { 102 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
85 // TODO(kinuko): refine this for better debug. 103 // TODO(kinuko): refine this for better debug.
86 return net::URLRequestJob::GetLoadState(); 104 return net::URLRequestJob::GetLoadState();
87 } 105 }
88 106
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 return; 143 return;
126 } 144 }
127 145
128 // We don't support multiple range requests in one single URL request. 146 // We don't support multiple range requests in one single URL request.
129 if (ranges.size() == 1U) 147 if (ranges.size() == 1U)
130 byte_range_ = ranges[0]; 148 byte_range_ = ranges[0];
131 } 149 }
132 150
133 bool ServiceWorkerURLRequestJob::ReadRawData( 151 bool ServiceWorkerURLRequestJob::ReadRawData(
134 net::IOBuffer* buf, int buf_size, int *bytes_read) { 152 net::IOBuffer* buf, int buf_size, int *bytes_read) {
153 DCHECK(buf);
154 DCHECK_GE(buf_size, 0);
155 DCHECK(bytes_read);
156 DCHECK(waiting_stream_url_.is_empty());
157 if (stream_.get()) {
158 switch (stream_->ReadRawData(buf, buf_size, bytes_read)) {
159 case Stream::STREAM_HAS_DATA:
160 DCHECK_GT(*bytes_read, 0);
161 return true;
162 case Stream::STREAM_COMPLETE:
163 DCHECK(!*bytes_read);
164 return true;
165 case Stream::STREAM_EMPTY:
166 stream_pending_buffer_ = buf;
167 stream_pending_buffer_size_ = buf_size;
168 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
169 return false;
170 case Stream::STREAM_ABORTED:
171 // Handle this as connection reset.
172 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
173 net::ERR_CONNECTION_RESET));
174 return false;
175 }
176 NOTREACHED();
177 return false;
178 }
179
135 if (!blob_request_) { 180 if (!blob_request_) {
136 *bytes_read = 0; 181 *bytes_read = 0;
137 return true; 182 return true;
138 } 183 }
139
140 blob_request_->Read(buf, buf_size, bytes_read); 184 blob_request_->Read(buf, buf_size, bytes_read);
141 net::URLRequestStatus status = blob_request_->status(); 185 net::URLRequestStatus status = blob_request_->status();
142 SetStatus(status); 186 SetStatus(status);
143 if (status.is_io_pending()) 187 if (status.is_io_pending())
144 return false; 188 return false;
145 return status.is_success(); 189 return status.is_success();
146 } 190 }
147 191
148 void ServiceWorkerURLRequestJob::OnReceivedRedirect( 192 void ServiceWorkerURLRequestJob::OnReceivedRedirect(
149 net::URLRequest* request, 193 net::URLRequest* request,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 SetStatus(request->status()); 242 SetStatus(request->status());
199 if (!request->status().is_success()) { 243 if (!request->status().is_success()) {
200 NotifyDone(request->status()); 244 NotifyDone(request->status());
201 return; 245 return;
202 } 246 }
203 NotifyReadComplete(bytes_read); 247 NotifyReadComplete(bytes_read);
204 if (bytes_read == 0) 248 if (bytes_read == 0)
205 NotifyDone(request->status()); 249 NotifyDone(request->status());
206 } 250 }
207 251
252 void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
253 // Clear the IO_PENDING status.
254 SetStatus(net::URLRequestStatus());
255 // Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData
256 // operation waiting for IO completion.
257 if (!stream_pending_buffer_.get())
258 return;
259
260 // stream_pending_buffer_ is set to the IOBuffer instance provided to
261 // ReadRawData() by URLRequestJob.
262
263 int bytes_read = 0;
264 switch (stream_->ReadRawData(
265 stream_pending_buffer_.get(), stream_pending_buffer_size_, &bytes_read)) {
266 case Stream::STREAM_HAS_DATA:
267 DCHECK_GT(bytes_read, 0);
268 break;
269 case Stream::STREAM_COMPLETE:
270 // Calling NotifyReadComplete call with 0 signals completion.
tyoshino (SeeGerritForStatus) 2014/12/08 09:36:56 s/call//
horo 2014/12/09 04:23:55 Done.
271 DCHECK(!bytes_read);
272 break;
273 case Stream::STREAM_EMPTY:
274 NOTREACHED();
275 break;
276 case Stream::STREAM_ABORTED:
277 // Handle this as connection reset.
278 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
279 net::ERR_CONNECTION_RESET));
280 break;
281 }
282
283 // Clear the buffers before notifying the read is complete, so that it is
284 // safe for the observer to read.
285 stream_pending_buffer_ = nullptr;
286 stream_pending_buffer_size_ = 0;
287 NotifyReadComplete(bytes_read);
288 }
289
290 void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) {
291 StreamContext* stream_context =
292 GetStreamContextForResourceContext(resource_context_);
293 stream_context->registry()->RemoveRegisterObserver(waiting_stream_url_);
294 waiting_stream_url_ = GURL();
295 stream_ = stream;
296 stream_->SetReadObserver(this);
297 CommitResponseHeader();
298 }
299
208 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { 300 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
209 if (!http_response_info_) 301 if (!http_response_info_)
210 return NULL; 302 return nullptr;
211 if (range_response_info_) 303 if (range_response_info_)
212 return range_response_info_.get(); 304 return range_response_info_.get();
213 return http_response_info_.get(); 305 return http_response_info_.get();
214 } 306 }
215 307
216 void ServiceWorkerURLRequestJob::GetExtraResponseInfo( 308 void ServiceWorkerURLRequestJob::GetExtraResponseInfo(
217 bool* was_fetched_via_service_worker, 309 bool* was_fetched_via_service_worker,
218 bool* was_fallback_required_by_service_worker, 310 bool* was_fallback_required_by_service_worker,
219 GURL* original_url_via_service_worker, 311 GURL* original_url_via_service_worker,
220 blink::WebServiceWorkerResponseType* response_type_via_service_worker, 312 blink::WebServiceWorkerResponseType* response_type_via_service_worker,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 345 }
254 346
255 void ServiceWorkerURLRequestJob::StartRequest() { 347 void ServiceWorkerURLRequestJob::StartRequest() {
256 switch (response_type_) { 348 switch (response_type_) {
257 case NOT_DETERMINED: 349 case NOT_DETERMINED:
258 NOTREACHED(); 350 NOTREACHED();
259 return; 351 return;
260 352
261 case FALLBACK_TO_NETWORK: 353 case FALLBACK_TO_NETWORK:
262 // Restart the request to create a new job. Our request handler will 354 // Restart the request to create a new job. Our request handler will
263 // return NULL, and the default job (which will hit network) should be 355 // return nullptr, and the default job (which will hit network) should be
264 // created. 356 // created.
265 NotifyRestartRequired(); 357 NotifyRestartRequired();
266 return; 358 return;
267 359
268 case FORWARD_TO_SERVICE_WORKER: 360 case FORWARD_TO_SERVICE_WORKER:
269 DCHECK(provider_host_ && provider_host_->active_version()); 361 DCHECK(provider_host_ && provider_host_->active_version());
270 DCHECK(!fetch_dispatcher_); 362 DCHECK(!fetch_dispatcher_);
271 // Send a fetch event to the ServiceWorker associated to the 363 // Send a fetch event to the ServiceWorker associated to the
272 // provider_host. 364 // provider_host.
273 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( 365 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 // Treat a response whose status is 0 as a Network Error. 523 // Treat a response whose status is 0 as a Network Error.
432 if (response.status_code == 0) { 524 if (response.status_code == 0) {
433 NotifyDone( 525 NotifyDone(
434 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); 526 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
435 return; 527 return;
436 } 528 }
437 529
438 fetch_end_time_ = base::TimeTicks::Now(); 530 fetch_end_time_ = base::TimeTicks::Now();
439 load_timing_info_.send_end = fetch_end_time_; 531 load_timing_info_.send_end = fetch_end_time_;
440 532
533 // Set up a request for reading the stream.
534 if (response.stream_url.is_valid()) {
535 DCHECK(response.blob_uuid.empty());
536 response_url_ = response.url;
537 service_worker_response_type_ = response.response_type;
538 CreateResponseHeader(
539 response.status_code, response.status_text, response.headers);
540 load_timing_info_.receive_headers_end = base::TimeTicks::Now();
541 StreamContext* stream_context =
542 GetStreamContextForResourceContext(resource_context_);
543 stream_ =
544 stream_context->registry()->GetStream(response.stream_url);
545 if (!stream_.get()) {
546 waiting_stream_url_ = response.stream_url;
547 // Wait for StreamHostMsg_StartBuilding message from the ServieWorker.
tyoshino (SeeGerritForStatus) 2014/12/08 09:36:56 Servie -> Service
horo 2014/12/09 04:23:55 Done.
548 stream_context->registry()->SetRegisterObserver(waiting_stream_url_,
549 this);
550 return;
551 }
552 stream_->SetReadObserver(this);
553 CommitResponseHeader();
554 return;
555 }
441 // Set up a request for reading the blob. 556 // Set up a request for reading the blob.
442 if (!response.blob_uuid.empty() && blob_storage_context_) { 557 if (!response.blob_uuid.empty() && blob_storage_context_) {
443 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 558 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
444 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 559 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
445 if (!blob_data_handle) { 560 if (!blob_data_handle) {
446 // The renderer gave us a bad blob UUID. 561 // The renderer gave us a bad blob UUID.
447 DeliverErrorResponse(); 562 DeliverErrorResponse();
448 return; 563 return;
449 } 564 }
450 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 565 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 606
492 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 607 void ServiceWorkerURLRequestJob::DeliverErrorResponse() {
493 // TODO(falken): Print an error to the console of the ServiceWorker and of 608 // TODO(falken): Print an error to the console of the ServiceWorker and of
494 // the requesting page. 609 // the requesting page.
495 CreateResponseHeader( 610 CreateResponseHeader(
496 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); 611 500, "Service Worker Response Error", ServiceWorkerHeaderMap());
497 CommitResponseHeader(); 612 CommitResponseHeader();
498 } 613 }
499 614
500 } // namespace content 615 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698