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

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: include set 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_.get()) {
nhiroki 2014/12/03 08:15:08 FYI: Boolean testing of scoped_refptr has been re-
horo 2014/12/05 05:51:53 Done.
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);
tyoshino (SeeGerritForStatus) 2014/12/03 08:13:33 can we assert that waiting_stream_url_ is empty he
horo 2014/12/05 05:51:53 Done.
156 if (stream_.get()) {
157 switch (stream_->ReadRawData(buf, buf_size, bytes_read)) {
158 case Stream::STREAM_HAS_DATA:
159 DCHECK_GT(*bytes_read, 0);
nhiroki 2014/12/03 08:15:07 You might want to add "return" here and "DCHECK(!b
horo 2014/12/05 05:51:53 Done.
160 case Stream::STREAM_COMPLETE:
161 return true;
162 case Stream::STREAM_EMPTY:
163 stream_pending_buffer_ = buf;
164 stream_pending_buffer_size_ = buf_size;
165 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
166 return false;
167 case Stream::STREAM_ABORTED:
168 // Handle this as connection reset.
169 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
170 net::ERR_CONNECTION_RESET));
171 return false;
172 }
173 NOTREACHED();
174 return false;
175 }
tyoshino (SeeGerritForStatus) 2014/12/03 08:13:33 insert a blank line here L176-L179 should be grou
horo 2014/12/05 05:51:53 Done.
135 if (!blob_request_) { 176 if (!blob_request_) {
136 *bytes_read = 0; 177 *bytes_read = 0;
137 return true; 178 return true;
138 } 179 }
139 180
140 blob_request_->Read(buf, buf_size, bytes_read); 181 blob_request_->Read(buf, buf_size, bytes_read);
141 net::URLRequestStatus status = blob_request_->status(); 182 net::URLRequestStatus status = blob_request_->status();
142 SetStatus(status); 183 SetStatus(status);
143 if (status.is_io_pending()) 184 if (status.is_io_pending())
144 return false; 185 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 SetStatus(request->status()); 239 SetStatus(request->status());
199 if (!request->status().is_success()) { 240 if (!request->status().is_success()) {
200 NotifyDone(request->status()); 241 NotifyDone(request->status());
201 return; 242 return;
202 } 243 }
203 NotifyReadComplete(bytes_read); 244 NotifyReadComplete(bytes_read);
204 if (bytes_read == 0) 245 if (bytes_read == 0)
205 NotifyDone(request->status()); 246 NotifyDone(request->status());
206 } 247 }
207 248
249 void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
250 // Clear the IO_PENDING status.
251 SetStatus(net::URLRequestStatus());
252 // Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData()
tyoshino (SeeGerritForStatus) 2014/12/03 08:13:33 stream_pending_buffer_
horo 2014/12/05 05:51:53 Done.
253 // operation waiting for IO completion.
254 if (!stream_pending_buffer_.get())
255 return;
256
257 // stream_pending_buffer_ is set to the IOBuffer instance provided to
258 // ReadRawData() by URLRequestJob.
259
260 int bytes_read = 0;
261 switch (stream_->ReadRawData(
262 stream_pending_buffer_.get(), stream_pending_buffer_size_, &bytes_read)) {
263 case Stream::STREAM_HAS_DATA:
264 DCHECK_GT(bytes_read, 0);
265 break;
266 case Stream::STREAM_COMPLETE:
267 // Calling NotifyReadComplete call with 0 signals completion.
268 DCHECK(!bytes_read);
269 break;
270 case Stream::STREAM_EMPTY:
271 NOTREACHED();
272 break;
273 case Stream::STREAM_ABORTED:
274 // Handle this as connection reset.
275 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
276 net::ERR_CONNECTION_RESET));
277 break;
278 }
279
280 // Clear the buffers before notifying the read is complete, so that it is
281 // safe for the observer to read.
282 stream_pending_buffer_ = nullptr;
283 stream_pending_buffer_size_ = 0;
284 NotifyReadComplete(bytes_read);
285 }
286
287 void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) {
288 StreamContext* stream_context =
289 GetStreamContextForResourceContext(resource_context_);
290 stream_context->registry()->RemoveRegisterObserver(waiting_stream_url_);
291 waiting_stream_url_ = GURL();
292 stream_ = stream;
293 stream_->SetReadObserver(this);
294 CommitResponseHeader();
295 }
296
208 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { 297 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
209 if (!http_response_info_) 298 if (!http_response_info_)
210 return NULL; 299 return nullptr;
211 if (range_response_info_) 300 if (range_response_info_)
212 return range_response_info_.get(); 301 return range_response_info_.get();
213 return http_response_info_.get(); 302 return http_response_info_.get();
214 } 303 }
215 304
216 void ServiceWorkerURLRequestJob::GetExtraResponseInfo( 305 void ServiceWorkerURLRequestJob::GetExtraResponseInfo(
217 bool* was_fetched_via_service_worker, 306 bool* was_fetched_via_service_worker,
218 bool* was_fallback_required_by_service_worker, 307 bool* was_fallback_required_by_service_worker,
219 GURL* original_url_via_service_worker, 308 GURL* original_url_via_service_worker,
220 blink::WebServiceWorkerResponseType* response_type_via_service_worker, 309 blink::WebServiceWorkerResponseType* response_type_via_service_worker,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 342 }
254 343
255 void ServiceWorkerURLRequestJob::StartRequest() { 344 void ServiceWorkerURLRequestJob::StartRequest() {
256 switch (response_type_) { 345 switch (response_type_) {
257 case NOT_DETERMINED: 346 case NOT_DETERMINED:
258 NOTREACHED(); 347 NOTREACHED();
259 return; 348 return;
260 349
261 case FALLBACK_TO_NETWORK: 350 case FALLBACK_TO_NETWORK:
262 // Restart the request to create a new job. Our request handler will 351 // 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 352 // return nullptr, and the default job (which will hit network) should be
264 // created. 353 // created.
265 NotifyRestartRequired(); 354 NotifyRestartRequired();
266 return; 355 return;
267 356
268 case FORWARD_TO_SERVICE_WORKER: 357 case FORWARD_TO_SERVICE_WORKER:
269 DCHECK(provider_host_ && provider_host_->active_version()); 358 DCHECK(provider_host_ && provider_host_->active_version());
270 DCHECK(!fetch_dispatcher_); 359 DCHECK(!fetch_dispatcher_);
271 // Send a fetch event to the ServiceWorker associated to the 360 // Send a fetch event to the ServiceWorker associated to the
272 // provider_host. 361 // provider_host.
273 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( 362 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. 520 // Treat a response whose status is 0 as a Network Error.
432 if (response.status_code == 0) { 521 if (response.status_code == 0) {
433 NotifyDone( 522 NotifyDone(
434 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); 523 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
435 return; 524 return;
436 } 525 }
437 526
438 fetch_end_time_ = base::TimeTicks::Now(); 527 fetch_end_time_ = base::TimeTicks::Now();
439 load_timing_info_.send_end = fetch_end_time_; 528 load_timing_info_.send_end = fetch_end_time_;
440 529
530 // Set up a request for reading the stream.
531 if (response.stream_url.is_valid()) {
532 DCHECK(response.blob_uuid.empty());
533 response_url_ = response.url;
534 service_worker_response_type_ = response.response_type;
535 CreateResponseHeader(
536 response.status_code, response.status_text, response.headers);
537 load_timing_info_.receive_headers_end = base::TimeTicks::Now();
538 StreamContext* stream_context =
539 GetStreamContextForResourceContext(resource_context_);
540 stream_ =
541 stream_context->registry()->GetStream(response.stream_url);
542 if (!stream_.get()) {
543 waiting_stream_url_ = response.stream_url;
544 // Wait for StreamHostMsg_StartBuilding message from the ServieWorker.
545 stream_context->registry()->SetRegisterObserver(waiting_stream_url_,
546 this);
547 return;
548 }
549 stream_->SetReadObserver(this);
550 CommitResponseHeader();
551 return;
552 }
441 // Set up a request for reading the blob. 553 // Set up a request for reading the blob.
442 if (!response.blob_uuid.empty() && blob_storage_context_) { 554 if (!response.blob_uuid.empty() && blob_storage_context_) {
443 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 555 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
444 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 556 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
445 if (!blob_data_handle) { 557 if (!blob_data_handle) {
446 // The renderer gave us a bad blob UUID. 558 // The renderer gave us a bad blob UUID.
447 DeliverErrorResponse(); 559 DeliverErrorResponse();
448 return; 560 return;
449 } 561 }
450 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 562 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 603
492 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 604 void ServiceWorkerURLRequestJob::DeliverErrorResponse() {
493 // TODO(falken): Print an error to the console of the ServiceWorker and of 605 // TODO(falken): Print an error to the console of the ServiceWorker and of
494 // the requesting page. 606 // the requesting page.
495 CreateResponseHeader( 607 CreateResponseHeader(
496 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); 608 500, "Service Worker Response Error", ServiceWorkerHeaderMap());
497 CommitResponseHeader(); 609 CommitResponseHeader();
498 } 610 }
499 611
500 } // namespace content 612 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698