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

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

Issue 658583006: [ServiceWorkerCache] Make ServiceWorkerCache::Put guarantee callback like the header says (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 1 month 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_cache.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 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_cache.h" 5 #include "content/browser/service_worker/service_worker_cache.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/guid.h" 10 #include "base/guid.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 scoped_refptr<storage::BlobData> blob) 87 scoped_refptr<storage::BlobData> blob)
88 : buffer(buff), blob_data(blob), total_bytes_read(0) {} 88 : buffer(buff), blob_data(blob), total_bytes_read(0) {}
89 89
90 scoped_refptr<net::IOBufferWithSize> buffer; 90 scoped_refptr<net::IOBufferWithSize> buffer;
91 scoped_refptr<storage::BlobData> blob_data; 91 scoped_refptr<storage::BlobData> blob_data;
92 int total_bytes_read; 92 int total_bytes_read;
93 93
94 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext); 94 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext);
95 }; 95 };
96 96
97 // Streams data from a blob and writes it to a given disk_cache::Entry.
98 class BlobReader : public net::URLRequest::Delegate {
99 public:
100 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
101 EntryAndBoolCallback;
102
103 BlobReader()
104 : cache_entry_offset_(0),
105 buffer_(new net::IOBufferWithSize(kBufferSize)),
106 weak_ptr_factory_(this) {}
107
108 // |entry| is passed to the callback once complete.
109 void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
110 net::URLRequestContext* request_context,
111 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
112 const EntryAndBoolCallback& callback) {
113 DCHECK(entry);
114 entry_ = entry.Pass();
115 callback_ = callback;
116 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
117 blob_data_handle.Pass(), request_context, this);
118 blob_request_->Start();
119 }
120
121 // net::URLRequest::Delegate overrides for reading blobs.
122 void OnReceivedRedirect(net::URLRequest* request,
123 const net::RedirectInfo& redirect_info,
124 bool* defer_redirect) override {
125 NOTREACHED();
126 }
127 void OnAuthRequired(net::URLRequest* request,
128 net::AuthChallengeInfo* auth_info) override {
129 NOTREACHED();
130 }
131 void OnCertificateRequested(
132 net::URLRequest* request,
133 net::SSLCertRequestInfo* cert_request_info) override {
134 NOTREACHED();
135 }
136 void OnSSLCertificateError(net::URLRequest* request,
137 const net::SSLInfo& ssl_info,
138 bool fatal) override {
139 NOTREACHED();
140 }
141 void OnBeforeNetworkStart(net::URLRequest* request, bool* defer) override {
142 NOTREACHED();
143 }
144
145 void OnResponseStarted(net::URLRequest* request) override {
146 if (!request->status().is_success()) {
147 callback_.Run(entry_.Pass(), false);
148 return;
149 }
150 ReadFromBlob();
151 }
152
153 virtual void ReadFromBlob() {
154 int bytes_read = 0;
155 bool done =
156 blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
157 if (done)
158 OnReadCompleted(blob_request_.get(), bytes_read);
159 }
160
161 void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
162 if (!request->status().is_success()) {
163 callback_.Run(entry_.Pass(), false);
164 return;
165 }
166
167 if (bytes_read == 0) {
168 callback_.Run(entry_.Pass(), true);
169 return;
170 }
171
172 net::CompletionCallback cache_write_callback =
173 base::Bind(&BlobReader::DidWriteDataToEntry,
174 weak_ptr_factory_.GetWeakPtr(),
175 bytes_read);
176
177 int rv = entry_->WriteData(INDEX_RESPONSE_BODY,
178 cache_entry_offset_,
179 buffer_.get(),
180 bytes_read,
181 cache_write_callback,
182 true /* truncate */);
183 if (rv != net::ERR_IO_PENDING)
184 cache_write_callback.Run(rv);
185 }
186
187 void DidWriteDataToEntry(int expected_bytes, int rv) {
188 if (rv != expected_bytes) {
189 callback_.Run(entry_.Pass(), false);
190 return;
191 }
192
193 cache_entry_offset_ += rv;
194 ReadFromBlob();
195 }
196
197 private:
198 int cache_entry_offset_;
199 disk_cache::ScopedEntryPtr entry_;
200 scoped_ptr<net::URLRequest> blob_request_;
201 EntryAndBoolCallback callback_;
202 scoped_refptr<net::IOBufferWithSize> buffer_;
203 base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
204 };
205
206 // The state needed to pass between ServiceWorkerCache::Put callbacks.
207 struct PutContext {
208 PutContext(
209 const GURL& origin,
210 scoped_ptr<ServiceWorkerFetchRequest> request,
211 scoped_ptr<ServiceWorkerResponse> response,
212 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
213 const ServiceWorkerCache::ResponseCallback& callback,
214 net::URLRequestContext* request_context,
215 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
216 : origin(origin),
217 request(request.Pass()),
218 response(response.Pass()),
219 blob_data_handle(blob_data_handle.Pass()),
220 callback(callback),
221 request_context(request_context),
222 quota_manager_proxy(quota_manager_proxy),
223 cache_entry(NULL) {}
224 ~PutContext() {
225 if (cache_entry)
226 cache_entry->Close();
227 }
228
229 // Input parameters to the Put function.
230 GURL origin;
231 scoped_ptr<ServiceWorkerFetchRequest> request;
232 scoped_ptr<ServiceWorkerResponse> response;
233 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
234 ServiceWorkerCache::ResponseCallback callback;
235 net::URLRequestContext* request_context;
236 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
237
238 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
239 // CreateEntry.
240 disk_cache::Entry* cache_entry;
241
242 // The BlobDataHandle for the output ServiceWorkerResponse.
243 scoped_ptr<storage::BlobDataHandle> out_blob_data_handle;
244
245 DISALLOW_COPY_AND_ASSIGN(PutContext);
246 };
247
248 // Put callbacks
249 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv);
250 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
251 int expected_bytes,
252 int rv);
253 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
254 scoped_ptr<BlobReader> blob_reader,
255 disk_cache::ScopedEntryPtr entry,
256 bool success);
257
258 // Match callbacks 97 // Match callbacks
259 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 98 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
260 const ServiceWorkerCache::ResponseCallback& callback, 99 const ServiceWorkerCache::ResponseCallback& callback,
261 base::WeakPtr<storage::BlobStorageContext> blob_storage, 100 base::WeakPtr<storage::BlobStorageContext> blob_storage,
262 scoped_ptr<disk_cache::Entry*> entryptr, 101 scoped_ptr<disk_cache::Entry*> entryptr,
263 int rv); 102 int rv);
264 void MatchDidReadMetadata( 103 void MatchDidReadMetadata(
265 scoped_ptr<ServiceWorkerFetchRequest> request, 104 scoped_ptr<ServiceWorkerFetchRequest> request,
266 const ServiceWorkerCache::ResponseCallback& callback, 105 const ServiceWorkerCache::ResponseCallback& callback,
267 base::WeakPtr<storage::BlobStorageContext> blob_storage, 106 base::WeakPtr<storage::BlobStorageContext> blob_storage,
(...skipping 30 matching lines...) Expand all
298 const MetadataCallback& callback, 137 const MetadataCallback& callback,
299 const scoped_refptr<net::IOBufferWithSize>& buffer, 138 const scoped_refptr<net::IOBufferWithSize>& buffer,
300 int rv); 139 int rv);
301 140
302 // CreateBackend callbacks 141 // CreateBackend callbacks
303 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, 142 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
304 scoped_ptr<ScopedBackendPtr> backend_ptr, 143 scoped_ptr<ScopedBackendPtr> backend_ptr,
305 base::WeakPtr<ServiceWorkerCache> cache, 144 base::WeakPtr<ServiceWorkerCache> cache,
306 int rv); 145 int rv);
307 146
308 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv) {
309 if (rv != net::OK) {
310 put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists,
311 scoped_ptr<ServiceWorkerResponse>(),
312 scoped_ptr<storage::BlobDataHandle>());
313 return;
314 }
315
316 DCHECK(put_context->cache_entry);
317
318 ServiceWorkerCacheMetadata metadata;
319 ServiceWorkerCacheRequest* request_metadata = metadata.mutable_request();
320 request_metadata->set_method(put_context->request->method);
321 for (ServiceWorkerHeaderMap::const_iterator it =
322 put_context->request->headers.begin();
323 it != put_context->request->headers.end();
324 ++it) {
325 ServiceWorkerCacheHeaderMap* header_map = request_metadata->add_headers();
326 header_map->set_name(it->first);
327 header_map->set_value(it->second);
328 }
329
330 ServiceWorkerCacheResponse* response_metadata = metadata.mutable_response();
331 response_metadata->set_status_code(put_context->response->status_code);
332 response_metadata->set_status_text(put_context->response->status_text);
333 response_metadata->set_response_type(
334 WebResponseTypeToProtoResponseType(put_context->response->response_type));
335 for (ServiceWorkerHeaderMap::const_iterator it =
336 put_context->response->headers.begin();
337 it != put_context->response->headers.end();
338 ++it) {
339 ServiceWorkerCacheHeaderMap* header_map = response_metadata->add_headers();
340 header_map->set_name(it->first);
341 header_map->set_value(it->second);
342 }
343
344 scoped_ptr<std::string> serialized(new std::string());
345 if (!metadata.SerializeToString(serialized.get())) {
346 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
347 scoped_ptr<ServiceWorkerResponse>(),
348 scoped_ptr<storage::BlobDataHandle>());
349 return;
350 }
351
352 scoped_refptr<net::StringIOBuffer> buffer(
353 new net::StringIOBuffer(serialized.Pass()));
354
355 // Get a temporary copy of the entry pointer before passing it in base::Bind.
356 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry;
357
358 net::CompletionCallback write_headers_callback = base::Bind(
359 PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size());
360
361 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
362 0 /* offset */,
363 buffer.get(),
364 buffer->size(),
365 write_headers_callback,
366 true /* truncate */);
367
368 if (rv != net::ERR_IO_PENDING)
369 write_headers_callback.Run(rv);
370 }
371
372 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
373 int expected_bytes,
374 int rv) {
375 if (rv != expected_bytes) {
376 put_context->cache_entry->Doom();
377 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
378 scoped_ptr<ServiceWorkerResponse>(),
379 scoped_ptr<storage::BlobDataHandle>());
380 return;
381 }
382
383 // The metadata is written, now for the response content. The data is streamed
384 // from the blob into the cache entry.
385
386 if (put_context->response->blob_uuid.empty()) {
387 if (put_context->quota_manager_proxy.get()) {
388 put_context->quota_manager_proxy->NotifyStorageModified(
389 storage::QuotaClient::kServiceWorkerCache,
390 put_context->origin,
391 storage::kStorageTypeTemporary,
392 put_context->cache_entry->GetDataSize(INDEX_HEADERS));
393 }
394
395 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
396 put_context->response.Pass(),
397 scoped_ptr<storage::BlobDataHandle>());
398 return;
399 }
400
401 DCHECK(put_context->blob_data_handle);
402
403 disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
404 put_context->cache_entry = NULL;
405 scoped_ptr<BlobReader> reader(new BlobReader());
406 BlobReader* reader_ptr = reader.get();
407
408 // Grab some pointers before passing put_context in Bind.
409 net::URLRequestContext* request_context = put_context->request_context;
410 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
411 put_context->blob_data_handle.Pass();
412
413 reader_ptr->StreamBlobToCache(entry.Pass(),
414 request_context,
415 blob_data_handle.Pass(),
416 base::Bind(PutDidWriteBlobToCache,
417 base::Passed(put_context.Pass()),
418 base::Passed(reader.Pass())));
419 }
420
421 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
422 scoped_ptr<BlobReader> blob_reader,
423 disk_cache::ScopedEntryPtr entry,
424 bool success) {
425 DCHECK(entry);
426 put_context->cache_entry = entry.release();
427
428 if (!success) {
429 put_context->cache_entry->Doom();
430 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
431 scoped_ptr<ServiceWorkerResponse>(),
432 scoped_ptr<storage::BlobDataHandle>());
433 return;
434 }
435
436 if (put_context->quota_manager_proxy.get()) {
437 put_context->quota_manager_proxy->NotifyStorageModified(
438 storage::QuotaClient::kServiceWorkerCache,
439 put_context->origin,
440 storage::kStorageTypeTemporary,
441 put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
442 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
443 }
444
445 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
446 put_context->response.Pass(),
447 put_context->out_blob_data_handle.Pass());
448 }
449
450 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, 147 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
451 const ServiceWorkerCache::ResponseCallback& callback, 148 const ServiceWorkerCache::ResponseCallback& callback,
452 base::WeakPtr<storage::BlobStorageContext> blob_storage, 149 base::WeakPtr<storage::BlobStorageContext> blob_storage,
453 scoped_ptr<disk_cache::Entry*> entryptr, 150 scoped_ptr<disk_cache::Entry*> entryptr,
454 int rv) { 151 int rv) {
455 if (rv != net::OK) { 152 if (rv != net::OK) {
456 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, 153 callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
457 scoped_ptr<ServiceWorkerResponse>(), 154 scoped_ptr<ServiceWorkerResponse>(),
458 scoped_ptr<storage::BlobDataHandle>()); 155 scoped_ptr<storage::BlobDataHandle>());
459 return; 156 return;
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 callback.Run(ServiceWorkerCache::ErrorTypeStorage); 444 callback.Run(ServiceWorkerCache::ErrorTypeStorage);
748 return; 445 return;
749 } 446 }
750 447
751 cache->set_backend(backend_ptr->Pass()); 448 cache->set_backend(backend_ptr->Pass());
752 callback.Run(ServiceWorkerCache::ErrorTypeOK); 449 callback.Run(ServiceWorkerCache::ErrorTypeOK);
753 } 450 }
754 451
755 } // namespace 452 } // namespace
756 453
454 // Streams data from a blob and writes it to a given disk_cache::Entry.
455 class ServiceWorkerCache::BlobReader : public net::URLRequest::Delegate {
456 public:
457 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
458 EntryAndBoolCallback;
459
460 BlobReader()
461 : cache_entry_offset_(0),
462 buffer_(new net::IOBufferWithSize(kBufferSize)),
463 weak_ptr_factory_(this) {}
464
465 // |entry| is passed to the callback once complete.
466 void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
467 net::URLRequestContext* request_context,
468 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
469 const EntryAndBoolCallback& callback) {
470 DCHECK(entry);
471 entry_ = entry.Pass();
472 callback_ = callback;
473 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
474 blob_data_handle.Pass(), request_context, this);
475 blob_request_->Start();
476 }
477
478 // net::URLRequest::Delegate overrides for reading blobs.
479 void OnReceivedRedirect(net::URLRequest* request,
480 const net::RedirectInfo& redirect_info,
481 bool* defer_redirect) override {
482 NOTREACHED();
483 }
484 void OnAuthRequired(net::URLRequest* request,
485 net::AuthChallengeInfo* auth_info) override {
486 NOTREACHED();
487 }
488 void OnCertificateRequested(
489 net::URLRequest* request,
490 net::SSLCertRequestInfo* cert_request_info) override {
491 NOTREACHED();
492 }
493 void OnSSLCertificateError(net::URLRequest* request,
494 const net::SSLInfo& ssl_info,
495 bool fatal) override {
496 NOTREACHED();
497 }
498 void OnBeforeNetworkStart(net::URLRequest* request, bool* defer) override {
499 NOTREACHED();
500 }
501
502 void OnResponseStarted(net::URLRequest* request) override {
503 if (!request->status().is_success()) {
504 callback_.Run(entry_.Pass(), false);
505 return;
506 }
507 ReadFromBlob();
508 }
509
510 virtual void ReadFromBlob() {
511 int bytes_read = 0;
512 bool done =
513 blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
514 if (done)
515 OnReadCompleted(blob_request_.get(), bytes_read);
516 }
517
518 void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
519 if (!request->status().is_success()) {
520 callback_.Run(entry_.Pass(), false);
521 return;
522 }
523
524 if (bytes_read == 0) {
525 callback_.Run(entry_.Pass(), true);
526 return;
527 }
528
529 net::CompletionCallback cache_write_callback =
530 base::Bind(&BlobReader::DidWriteDataToEntry,
531 weak_ptr_factory_.GetWeakPtr(),
532 bytes_read);
533
534 int rv = entry_->WriteData(INDEX_RESPONSE_BODY,
535 cache_entry_offset_,
536 buffer_.get(),
537 bytes_read,
538 cache_write_callback,
539 true /* truncate */);
540 if (rv != net::ERR_IO_PENDING)
541 cache_write_callback.Run(rv);
542 }
543
544 void DidWriteDataToEntry(int expected_bytes, int rv) {
545 if (rv != expected_bytes) {
546 callback_.Run(entry_.Pass(), false);
547 return;
548 }
549
550 cache_entry_offset_ += rv;
551 ReadFromBlob();
552 }
553
554 private:
555 int cache_entry_offset_;
556 disk_cache::ScopedEntryPtr entry_;
557 scoped_ptr<net::URLRequest> blob_request_;
558 EntryAndBoolCallback callback_;
559 scoped_refptr<net::IOBufferWithSize> buffer_;
560 base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
561 };
562
757 // The state needed to pass between ServiceWorkerCache::Keys callbacks. 563 // The state needed to pass between ServiceWorkerCache::Keys callbacks.
758 struct ServiceWorkerCache::KeysContext { 564 struct ServiceWorkerCache::KeysContext {
759 KeysContext(const ServiceWorkerCache::RequestsCallback& callback, 565 KeysContext(const ServiceWorkerCache::RequestsCallback& callback,
760 base::WeakPtr<ServiceWorkerCache> cache) 566 base::WeakPtr<ServiceWorkerCache> cache)
761 : original_callback(callback), 567 : original_callback(callback),
762 cache(cache), 568 cache(cache),
763 out_keys(new ServiceWorkerCache::Requests()), 569 out_keys(new ServiceWorkerCache::Requests()),
764 enumerated_entry(NULL) {} 570 enumerated_entry(NULL) {}
765 571
766 ~KeysContext() { 572 ~KeysContext() {
(...skipping 15 matching lines...) Expand all
782 // The output of the Keys function. 588 // The output of the Keys function.
783 scoped_ptr<ServiceWorkerCache::Requests> out_keys; 589 scoped_ptr<ServiceWorkerCache::Requests> out_keys;
784 590
785 // Used for enumerating cache entries. 591 // Used for enumerating cache entries.
786 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; 592 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
787 disk_cache::Entry* enumerated_entry; 593 disk_cache::Entry* enumerated_entry;
788 594
789 DISALLOW_COPY_AND_ASSIGN(KeysContext); 595 DISALLOW_COPY_AND_ASSIGN(KeysContext);
790 }; 596 };
791 597
598 // The state needed to pass between ServiceWorkerCache::Put callbacks.
599 struct ServiceWorkerCache::PutContext {
600 PutContext(
601 const GURL& origin,
602 scoped_ptr<ServiceWorkerFetchRequest> request,
603 scoped_ptr<ServiceWorkerResponse> response,
604 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
605 const ServiceWorkerCache::ResponseCallback& callback,
606 base::WeakPtr<ServiceWorkerCache> cache,
607 net::URLRequestContext* request_context,
608 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
609 : origin(origin),
610 request(request.Pass()),
611 response(response.Pass()),
612 blob_data_handle(blob_data_handle.Pass()),
613 callback(callback),
614 cache(cache),
615 request_context(request_context),
616 quota_manager_proxy(quota_manager_proxy),
617 cache_entry(NULL) {}
618 ~PutContext() {
619 if (cache_entry)
620 cache_entry->Close();
621 }
622
623 // Input parameters to the Put function.
624 GURL origin;
625 scoped_ptr<ServiceWorkerFetchRequest> request;
626 scoped_ptr<ServiceWorkerResponse> response;
627 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
628 ServiceWorkerCache::ResponseCallback callback;
629 base::WeakPtr<ServiceWorkerCache> cache;
630 net::URLRequestContext* request_context;
631 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
632
633 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
634 // CreateEntry.
635 disk_cache::Entry* cache_entry;
636
637 // The BlobDataHandle for the output ServiceWorkerResponse.
638 scoped_ptr<storage::BlobDataHandle> out_blob_data_handle;
639
640 DISALLOW_COPY_AND_ASSIGN(PutContext);
641 };
642
792 // static 643 // static
793 scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( 644 scoped_refptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
794 const GURL& origin, 645 const GURL& origin,
795 net::URLRequestContext* request_context, 646 net::URLRequestContext* request_context,
796 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 647 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
797 base::WeakPtr<storage::BlobStorageContext> blob_context) { 648 base::WeakPtr<storage::BlobStorageContext> blob_context) {
798 return make_scoped_refptr(new ServiceWorkerCache(origin, 649 return make_scoped_refptr(new ServiceWorkerCache(origin,
799 base::FilePath(), 650 base::FilePath(),
800 request_context, 651 request_context,
801 quota_manager_proxy, 652 quota_manager_proxy,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 blob_data_handle = 686 blob_data_handle =
836 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); 687 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
837 if (!blob_data_handle) { 688 if (!blob_data_handle) {
838 callback.Run(ErrorTypeStorage, 689 callback.Run(ErrorTypeStorage,
839 scoped_ptr<ServiceWorkerResponse>(), 690 scoped_ptr<ServiceWorkerResponse>(),
840 scoped_ptr<storage::BlobDataHandle>()); 691 scoped_ptr<storage::BlobDataHandle>());
841 return; 692 return;
842 } 693 }
843 } 694 }
844 695
696 scoped_ptr<PutContext> put_context(
697 new PutContext(origin_,
698 request.Pass(),
699 response.Pass(),
700 blob_data_handle.Pass(),
701 callback,
702 weak_ptr_factory_.GetWeakPtr(),
703 request_context_,
704 quota_manager_proxy_));
705
706 if (put_context->blob_data_handle) {
707 // Grab another handle to the blob for the callback response.
708 put_context->out_blob_data_handle =
709 blob_storage_context_->GetBlobDataFromUUID(
710 put_context->response->blob_uuid);
711 }
712
845 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl, 713 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl,
846 weak_ptr_factory_.GetWeakPtr(), 714 base::Passed(put_context.Pass()));
847 base::Passed(request.Pass()),
848 base::Passed(response.Pass()),
849 base::Passed(blob_data_handle.Pass()),
850 callback);
851 715
852 if (!initialized_) { 716 if (!initialized_) {
853 Init(continuation); 717 Init(continuation);
854 return; 718 return;
855 } 719 }
856 720
857 continuation.Run(); 721 continuation.Run();
858 } 722 }
859 723
860 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request, 724 void ServiceWorkerCache::Match(scoped_ptr<ServiceWorkerFetchRequest> request,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 : origin_(origin), 868 : origin_(origin),
1005 path_(path), 869 path_(path),
1006 request_context_(request_context), 870 request_context_(request_context),
1007 quota_manager_proxy_(quota_manager_proxy), 871 quota_manager_proxy_(quota_manager_proxy),
1008 blob_storage_context_(blob_context), 872 blob_storage_context_(blob_context),
1009 initialized_(false), 873 initialized_(false),
1010 memory_only_(path.empty()), 874 memory_only_(path.empty()),
1011 weak_ptr_factory_(this) { 875 weak_ptr_factory_(this) {
1012 } 876 }
1013 877
1014 void ServiceWorkerCache::PutImpl( 878 // static
1015 scoped_ptr<ServiceWorkerFetchRequest> request, 879 void ServiceWorkerCache::PutImpl(scoped_ptr<PutContext> put_context) {
1016 scoped_ptr<ServiceWorkerResponse> response, 880 if (!put_context->cache || !put_context->cache->backend_) {
1017 scoped_ptr<storage::BlobDataHandle> blob_data_handle, 881 put_context->callback.Run(ErrorTypeStorage,
1018 const ResponseCallback& callback) { 882 scoped_ptr<ServiceWorkerResponse>(),
1019 if (!backend_) { 883 scoped_ptr<storage::BlobDataHandle>());
1020 callback.Run(ErrorTypeStorage,
1021 scoped_ptr<ServiceWorkerResponse>(),
1022 scoped_ptr<storage::BlobDataHandle>());
1023 return; 884 return;
1024 } 885 }
1025 886
1026 scoped_ptr<PutContext> put_context(new PutContext(origin_,
1027 request.Pass(),
1028 response.Pass(),
1029 blob_data_handle.Pass(),
1030 callback,
1031 request_context_,
1032 quota_manager_proxy_));
1033
1034 if (put_context->blob_data_handle) {
1035 // Grab another handle to the blob for the callback response.
1036 put_context->out_blob_data_handle =
1037 blob_storage_context_->GetBlobDataFromUUID(
1038 put_context->response->blob_uuid);
1039 }
1040
1041 disk_cache::Entry** entry_ptr = &put_context->cache_entry; 887 disk_cache::Entry** entry_ptr = &put_context->cache_entry;
1042 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 888 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
889 disk_cache::Backend* backend_ptr = put_context->cache->backend_.get();
1043 890
1044 net::CompletionCallback create_entry_callback = 891 net::CompletionCallback create_entry_callback =
1045 base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass())); 892 base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass()));
1046 893
1047 int rv = backend_->CreateEntry( 894 int create_rv = backend_ptr->CreateEntry(
1048 request_ptr->url.spec(), entry_ptr, create_entry_callback); 895 request_ptr->url.spec(), entry_ptr, create_entry_callback);
1049 896
1050 if (rv != net::ERR_IO_PENDING) 897 if (create_rv != net::ERR_IO_PENDING)
1051 create_entry_callback.Run(rv); 898 create_entry_callback.Run(create_rv);
1052 } 899 }
1053 900
1054 // static 901 // static
902 void ServiceWorkerCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context,
903 int rv) {
904 if (rv != net::OK) {
905 put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists,
906 scoped_ptr<ServiceWorkerResponse>(),
907 scoped_ptr<storage::BlobDataHandle>());
908 return;
909 }
910
911 DCHECK(put_context->cache_entry);
912
913 ServiceWorkerCacheMetadata metadata;
914 ServiceWorkerCacheRequest* request_metadata = metadata.mutable_request();
915 request_metadata->set_method(put_context->request->method);
916 for (ServiceWorkerHeaderMap::const_iterator it =
917 put_context->request->headers.begin();
918 it != put_context->request->headers.end();
919 ++it) {
920 ServiceWorkerCacheHeaderMap* header_map = request_metadata->add_headers();
921 header_map->set_name(it->first);
922 header_map->set_value(it->second);
923 }
924
925 ServiceWorkerCacheResponse* response_metadata = metadata.mutable_response();
926 response_metadata->set_status_code(put_context->response->status_code);
927 response_metadata->set_status_text(put_context->response->status_text);
928 response_metadata->set_response_type(
929 WebResponseTypeToProtoResponseType(put_context->response->response_type));
930 for (ServiceWorkerHeaderMap::const_iterator it =
931 put_context->response->headers.begin();
932 it != put_context->response->headers.end();
933 ++it) {
934 ServiceWorkerCacheHeaderMap* header_map = response_metadata->add_headers();
935 header_map->set_name(it->first);
936 header_map->set_value(it->second);
937 }
938
939 scoped_ptr<std::string> serialized(new std::string());
940 if (!metadata.SerializeToString(serialized.get())) {
941 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
942 scoped_ptr<ServiceWorkerResponse>(),
943 scoped_ptr<storage::BlobDataHandle>());
944 return;
945 }
946
947 scoped_refptr<net::StringIOBuffer> buffer(
948 new net::StringIOBuffer(serialized.Pass()));
949
950 // Get a temporary copy of the entry pointer before passing it in base::Bind.
951 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry;
952
953 net::CompletionCallback write_headers_callback = base::Bind(
954 PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size());
955
956 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
957 0 /* offset */,
958 buffer.get(),
959 buffer->size(),
960 write_headers_callback,
961 true /* truncate */);
962
963 if (rv != net::ERR_IO_PENDING)
964 write_headers_callback.Run(rv);
965 }
966
967 // static
968 void ServiceWorkerCache::PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
969 int expected_bytes,
970 int rv) {
971 if (rv != expected_bytes) {
972 put_context->cache_entry->Doom();
973 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
974 scoped_ptr<ServiceWorkerResponse>(),
975 scoped_ptr<storage::BlobDataHandle>());
976 return;
977 }
978
979 // The metadata is written, now for the response content. The data is streamed
980 // from the blob into the cache entry.
981
982 if (put_context->response->blob_uuid.empty()) {
983 if (put_context->quota_manager_proxy.get()) {
984 put_context->quota_manager_proxy->NotifyStorageModified(
985 storage::QuotaClient::kServiceWorkerCache,
986 put_context->origin,
987 storage::kStorageTypeTemporary,
988 put_context->cache_entry->GetDataSize(INDEX_HEADERS));
989 }
990
991 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
992 put_context->response.Pass(),
993 scoped_ptr<storage::BlobDataHandle>());
994 return;
995 }
996
997 DCHECK(put_context->blob_data_handle);
998
999 disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
1000 put_context->cache_entry = NULL;
1001 scoped_ptr<BlobReader> reader(new BlobReader());
1002 BlobReader* reader_ptr = reader.get();
1003
1004 // Grab some pointers before passing put_context in Bind.
1005 net::URLRequestContext* request_context = put_context->request_context;
1006 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
1007 put_context->blob_data_handle.Pass();
1008
1009 reader_ptr->StreamBlobToCache(entry.Pass(),
1010 request_context,
1011 blob_data_handle.Pass(),
1012 base::Bind(PutDidWriteBlobToCache,
1013 base::Passed(put_context.Pass()),
1014 base::Passed(reader.Pass())));
1015 }
1016
1017 // static
1018 void ServiceWorkerCache::PutDidWriteBlobToCache(
1019 scoped_ptr<PutContext> put_context,
1020 scoped_ptr<BlobReader> blob_reader,
1021 disk_cache::ScopedEntryPtr entry,
1022 bool success) {
1023 DCHECK(entry);
1024 put_context->cache_entry = entry.release();
1025
1026 if (!success) {
1027 put_context->cache_entry->Doom();
1028 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage,
1029 scoped_ptr<ServiceWorkerResponse>(),
1030 scoped_ptr<storage::BlobDataHandle>());
1031 return;
1032 }
1033
1034 if (put_context->quota_manager_proxy.get()) {
1035 put_context->quota_manager_proxy->NotifyStorageModified(
1036 storage::QuotaClient::kServiceWorkerCache,
1037 put_context->origin,
1038 storage::kStorageTypeTemporary,
1039 put_context->cache_entry->GetDataSize(INDEX_HEADERS) +
1040 put_context->cache_entry->GetDataSize(INDEX_RESPONSE_BODY));
1041 }
1042
1043 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK,
1044 put_context->response.Pass(),
1045 put_context->out_blob_data_handle.Pass());
1046 }
1047
1048 // static
1055 void ServiceWorkerCache::KeysDidOpenNextEntry( 1049 void ServiceWorkerCache::KeysDidOpenNextEntry(
1056 scoped_ptr<KeysContext> keys_context, 1050 scoped_ptr<KeysContext> keys_context,
1057 int rv) { 1051 int rv) {
1058 if (rv == net::ERR_FAILED) { 1052 if (rv == net::ERR_FAILED) {
1059 DCHECK(!keys_context->enumerated_entry); 1053 DCHECK(!keys_context->enumerated_entry);
1060 // Enumeration is complete, extract the requests from the entries. 1054 // Enumeration is complete, extract the requests from the entries.
1061 Entries::iterator iter = keys_context->entries.begin(); 1055 Entries::iterator iter = keys_context->entries.begin();
1062 KeysProcessNextEntry(keys_context.Pass(), iter); 1056 KeysProcessNextEntry(keys_context.Pass(), iter);
1063 return; 1057 return;
1064 } 1058 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 initialized_ = true; 1180 initialized_ = true;
1187 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); 1181 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
1188 it != init_callbacks_.end(); 1182 it != init_callbacks_.end();
1189 ++it) { 1183 ++it) {
1190 it->Run(); 1184 it->Run();
1191 } 1185 }
1192 init_callbacks_.clear(); 1186 init_callbacks_.clear();
1193 } 1187 }
1194 1188
1195 } // namespace content 1189 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698