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

Side by Side Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 1108083002: Create blobs from Disk Cache entries. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased to upstream CL, review this upload Created 5 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
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/cache_storage/cache_storage_cache.h" 5 #include "content/browser/cache_storage/cache_storage_cache.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/barrier_closure.h" 9 #include "base/barrier_closure.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 14 matching lines...) Expand all
25 #include "storage/browser/blob/blob_data_handle.h" 25 #include "storage/browser/blob/blob_data_handle.h"
26 #include "storage/browser/blob/blob_storage_context.h" 26 #include "storage/browser/blob/blob_storage_context.h"
27 #include "storage/browser/blob/blob_url_request_job_factory.h" 27 #include "storage/browser/blob/blob_url_request_job_factory.h"
28 #include "storage/browser/quota/quota_manager_proxy.h" 28 #include "storage/browser/quota/quota_manager_proxy.h"
29 #include "third_party/WebKit/public/platform/WebServiceWorkerResponseType.h" 29 #include "third_party/WebKit/public/platform/WebServiceWorkerResponseType.h"
30 30
31 namespace content { 31 namespace content {
32 32
33 namespace { 33 namespace {
34 34
35 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 35 class CacheStorageCacheExtraData : public storage::BlobDataBuilder::ExtraData {
36 EntryBoolCallback; 36 public:
37 explicit CacheStorageCacheExtraData(
38 const scoped_refptr<CacheStorageCache>& cache)
39 : cache_(cache) {}
40
41 private:
42 scoped_refptr<CacheStorageCache> cache_;
43 };
44
37 typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; 45 typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback;
38 46
39 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
40
41 // The maximum size of an individual cache. Ultimately cache size is controlled 47 // The maximum size of an individual cache. Ultimately cache size is controlled
42 // per-origin. 48 // per-origin.
43 const int kMaxCacheBytes = 512 * 1024 * 1024; 49 const int kMaxCacheBytes = 512 * 1024 * 1024;
44 50
45 // Buffer size for cache and blob reading/writing. 51 // Buffer size for cache and blob reading/writing.
46 const int kBufferSize = 1024 * 512; 52 const int kBufferSize = 1024 * 512;
47 53
48 void NotReachedCompletionCallback(int rv) { 54 void NotReachedCompletionCallback(int rv) {
49 NOTREACHED(); 55 NOTREACHED();
50 } 56 }
(...skipping 27 matching lines...) Expand all
78 return CacheResponse::DEFAULT_TYPE; 84 return CacheResponse::DEFAULT_TYPE;
79 case blink::WebServiceWorkerResponseTypeError: 85 case blink::WebServiceWorkerResponseTypeError:
80 return CacheResponse::ERROR_TYPE; 86 return CacheResponse::ERROR_TYPE;
81 case blink::WebServiceWorkerResponseTypeOpaque: 87 case blink::WebServiceWorkerResponseTypeOpaque:
82 return CacheResponse::OPAQUE_TYPE; 88 return CacheResponse::OPAQUE_TYPE;
83 } 89 }
84 NOTREACHED(); 90 NOTREACHED();
85 return CacheResponse::OPAQUE_TYPE; 91 return CacheResponse::OPAQUE_TYPE;
86 } 92 }
87 93
88 // Copy headers out of a cache entry and into a protobuf. The callback is
89 // guaranteed to be run.
90 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback);
91 void ReadMetadataDidReadMetadata(
92 disk_cache::Entry* entry,
93 const MetadataCallback& callback,
94 const scoped_refptr<net::IOBufferWithSize>& buffer,
95 int rv);
96
97 bool VaryMatches(const ServiceWorkerHeaderMap& request, 94 bool VaryMatches(const ServiceWorkerHeaderMap& request,
98 const ServiceWorkerHeaderMap& cached_request, 95 const ServiceWorkerHeaderMap& cached_request,
99 const ServiceWorkerHeaderMap& response) { 96 const ServiceWorkerHeaderMap& response) {
100 ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary"); 97 ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary");
101 if (vary_iter == response.end()) 98 if (vary_iter == response.end())
102 return true; 99 return true;
103 100
104 std::vector<std::string> vary_keys; 101 std::vector<std::string> vary_keys;
105 Tokenize(vary_iter->second, ",", &vary_keys); 102 Tokenize(vary_iter->second, ",", &vary_keys);
106 for (std::vector<std::string>::const_iterator it = vary_keys.begin(); 103 for (std::vector<std::string>::const_iterator it = vary_keys.begin();
(...skipping 15 matching lines...) Expand all
122 // If the header exists in one, it exists in both. Verify that the values 119 // If the header exists in one, it exists in both. Verify that the values
123 // are equal. 120 // are equal.
124 if (request_iter != request.end() && 121 if (request_iter != request.end() &&
125 request_iter->second != cached_request_iter->second) 122 request_iter->second != cached_request_iter->second)
126 return false; 123 return false;
127 } 124 }
128 125
129 return true; 126 return true;
130 } 127 }
131 128
132 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) { 129 typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback;
jkarlin 2015/05/29 14:59:41 Why move this? I prefer to have typdefs and enums
gavinp 2015/05/29 18:06:07 I moved it back. The reason I moved it down was f
133 DCHECK(entry);
134 130
135 scoped_refptr<net::IOBufferWithSize> buffer( 131 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
jkarlin 2015/05/29 14:59:41 Ditto.
gavinp 2015/05/29 18:06:07 Done.
136 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
137
138 net::CompletionCallback read_header_callback =
139 base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer);
140
141 int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(),
142 read_header_callback);
143
144 if (read_rv != net::ERR_IO_PENDING)
145 read_header_callback.Run(read_rv);
146 }
147 132
148 void ReadMetadataDidReadMetadata( 133 void ReadMetadataDidReadMetadata(
149 disk_cache::Entry* entry, 134 disk_cache::Entry* entry,
150 const MetadataCallback& callback, 135 const MetadataCallback& callback,
151 const scoped_refptr<net::IOBufferWithSize>& buffer, 136 const scoped_refptr<net::IOBufferWithSize>& buffer,
152 int rv) { 137 int rv) {
153 if (rv != buffer->size()) { 138 if (rv != buffer->size()) {
154 callback.Run(scoped_ptr<CacheMetadata>()); 139 callback.Run(scoped_ptr<CacheMetadata>());
155 return; 140 return;
156 } 141 }
157 142
158 scoped_ptr<CacheMetadata> metadata(new CacheMetadata()); 143 scoped_ptr<CacheMetadata> metadata(new CacheMetadata());
159 144
160 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { 145 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
161 callback.Run(scoped_ptr<CacheMetadata>()); 146 callback.Run(scoped_ptr<CacheMetadata>());
162 return; 147 return;
163 } 148 }
164 149
165 callback.Run(metadata.Pass()); 150 callback.Run(metadata.Pass());
166 } 151 }
167 152
153 // Copy headers out of a cache entry and into a protobuf. The callback is
154 // guaranteed to be run.
155 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) {
156 DCHECK(entry);
157
158 scoped_refptr<net::IOBufferWithSize> buffer(
159 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
160
161 net::CompletionCallback read_header_callback =
162 base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer);
163
164 int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(),
165 read_header_callback);
166
167 if (read_rv != net::ERR_IO_PENDING)
168 read_header_callback.Run(read_rv);
169 }
170
168 } // namespace 171 } // namespace
169 172
170 // Streams data from a blob and writes it to a given disk_cache::Entry. 173 // Streams data from a blob and writes it to a given disk_cache::Entry.
171 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate { 174 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate {
172 public: 175 public:
173 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 176 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
174 EntryAndBoolCallback; 177 EntryAndBoolCallback;
175 178
176 BlobReader() 179 BlobReader()
177 : cache_entry_offset_(0), 180 : cache_entry_offset_(0),
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 300
298 // Used for enumerating cache entries. 301 // Used for enumerating cache entries.
299 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; 302 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
300 disk_cache::Entry* enumerated_entry; 303 disk_cache::Entry* enumerated_entry;
301 304
302 DISALLOW_COPY_AND_ASSIGN(KeysContext); 305 DISALLOW_COPY_AND_ASSIGN(KeysContext);
303 }; 306 };
304 307
305 struct CacheStorageCache::MatchContext { 308 struct CacheStorageCache::MatchContext {
306 MatchContext(scoped_ptr<ServiceWorkerFetchRequest> request, 309 MatchContext(scoped_ptr<ServiceWorkerFetchRequest> request,
307 const CacheStorageCache::ResponseCallback& callback, 310 const CacheStorageCache::ResponseCallback& callback)
308 base::WeakPtr<storage::BlobStorageContext> blob_storage_context) 311 : request(request.Pass()), original_callback(callback) {}
309 : request(request.Pass()),
310 original_callback(callback),
311 blob_storage_context(blob_storage_context),
312 entry(nullptr),
313 total_bytes_read(0) {}
314 312
315 ~MatchContext() {
316 if (entry)
317 entry->Close();
318 }
319
320 // Input
321 scoped_ptr<ServiceWorkerFetchRequest> request; 313 scoped_ptr<ServiceWorkerFetchRequest> request;
322 CacheStorageCache::ResponseCallback original_callback; 314 CacheStorageCache::ResponseCallback original_callback;
323 base::WeakPtr<storage::BlobStorageContext> blob_storage_context; 315 disk_cache::ScopedEntryPtr entry;
324 disk_cache::Entry* entry;
325
326 // Output
327 scoped_ptr<ServiceWorkerResponse> response;
328 scoped_ptr<storage::BlobDataBuilder> blob_data;
329
330 // For reading the cache entry data into a blob.
331 scoped_refptr<net::IOBufferWithSize> response_body_buffer;
332 size_t total_bytes_read;
333 316
334 DISALLOW_COPY_AND_ASSIGN(MatchContext); 317 DISALLOW_COPY_AND_ASSIGN(MatchContext);
335 }; 318 };
336 319
337 // The state needed to pass between CacheStorageCache::Put callbacks. 320 // The state needed to pass between CacheStorageCache::Put callbacks.
338 struct CacheStorageCache::PutContext { 321 struct CacheStorageCache::PutContext {
339 PutContext( 322 PutContext(
340 const GURL& origin, 323 const GURL& origin,
341 scoped_ptr<ServiceWorkerFetchRequest> request, 324 scoped_ptr<ServiceWorkerFetchRequest> request,
342 scoped_ptr<ServiceWorkerResponse> response, 325 scoped_ptr<ServiceWorkerResponse> response,
343 scoped_ptr<storage::BlobDataHandle> blob_data_handle, 326 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
344 const CacheStorageCache::ErrorCallback& callback, 327 const CacheStorageCache::ErrorCallback& callback,
345 net::URLRequestContext* request_context, 328 net::URLRequestContext* request_context,
346 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy) 329 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
347 : origin(origin), 330 : origin(origin),
348 request(request.Pass()), 331 request(request.Pass()),
349 response(response.Pass()), 332 response(response.Pass()),
350 blob_data_handle(blob_data_handle.Pass()), 333 blob_data_handle(blob_data_handle.Pass()),
351 callback(callback), 334 callback(callback),
352 request_context(request_context), 335 request_context(request_context),
353 quota_manager_proxy(quota_manager_proxy), 336 quota_manager_proxy(quota_manager_proxy) {}
354 cache_entry(NULL) {}
355 ~PutContext() {
356 if (cache_entry)
357 cache_entry->Close();
358 }
359 337
360 // Input parameters to the Put function. 338 // Input parameters to the Put function.
361 GURL origin; 339 GURL origin;
362 scoped_ptr<ServiceWorkerFetchRequest> request; 340 scoped_ptr<ServiceWorkerFetchRequest> request;
363 scoped_ptr<ServiceWorkerResponse> response; 341 scoped_ptr<ServiceWorkerResponse> response;
364 scoped_ptr<storage::BlobDataHandle> blob_data_handle; 342 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
365 CacheStorageCache::ErrorCallback callback; 343 CacheStorageCache::ErrorCallback callback;
366 net::URLRequestContext* request_context; 344 net::URLRequestContext* request_context;
367 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy; 345 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
368 346 disk_cache::ScopedEntryPtr cache_entry;
369 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
370 // CreateEntry.
371 disk_cache::Entry* cache_entry;
372 347
373 DISALLOW_COPY_AND_ASSIGN(PutContext); 348 DISALLOW_COPY_AND_ASSIGN(PutContext);
374 }; 349 };
375 350
376 // static 351 // static
377 scoped_refptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( 352 scoped_refptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
378 const GURL& origin, 353 const GURL& origin,
379 net::URLRequestContext* request_context, 354 net::URLRequestContext* request_context,
380 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 355 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
381 base::WeakPtr<storage::BlobStorageContext> blob_context) { 356 base::WeakPtr<storage::BlobStorageContext> blob_context) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 const ResponseCallback& callback) { 549 const ResponseCallback& callback) {
575 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 550 DCHECK(backend_state_ != BACKEND_UNINITIALIZED);
576 if (backend_state_ != BACKEND_OPEN) { 551 if (backend_state_ != BACKEND_OPEN) {
577 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 552 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
578 scoped_ptr<ServiceWorkerResponse>(), 553 scoped_ptr<ServiceWorkerResponse>(),
579 scoped_ptr<storage::BlobDataHandle>()); 554 scoped_ptr<storage::BlobDataHandle>());
580 return; 555 return;
581 } 556 }
582 557
583 scoped_ptr<MatchContext> match_context( 558 scoped_ptr<MatchContext> match_context(
584 new MatchContext(request.Pass(), callback, blob_storage_context_)); 559 new MatchContext(request.Pass(), callback));
585 560
586 disk_cache::Entry** entry_ptr = &match_context->entry; 561 scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*());
562 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
587 ServiceWorkerFetchRequest* request_ptr = match_context->request.get(); 563 ServiceWorkerFetchRequest* request_ptr = match_context->request.get();
588 564
589 net::CompletionCallback open_entry_callback = base::Bind( 565 net::CompletionCallback open_entry_callback = base::Bind(
590 &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), 566 &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(),
567 base::Passed(scoped_entry_ptr.Pass()),
591 base::Passed(match_context.Pass())); 568 base::Passed(match_context.Pass()));
592 569
593 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr, 570 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
594 open_entry_callback); 571 open_entry_callback);
595 if (rv != net::ERR_IO_PENDING) 572 if (rv != net::ERR_IO_PENDING)
596 open_entry_callback.Run(rv); 573 open_entry_callback.Run(rv);
597 } 574 }
598 575
599 void CacheStorageCache::MatchDidOpenEntry( 576 void CacheStorageCache::MatchDidOpenEntry(
577 scoped_ptr<disk_cache::Entry*> entry_ptr,
600 scoped_ptr<MatchContext> match_context, 578 scoped_ptr<MatchContext> match_context,
601 int rv) { 579 int rv) {
602 if (rv != net::OK) { 580 if (rv != net::OK) {
603 match_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, 581 match_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
604 scoped_ptr<ServiceWorkerResponse>(), 582 scoped_ptr<ServiceWorkerResponse>(),
605 scoped_ptr<storage::BlobDataHandle>()); 583 scoped_ptr<storage::BlobDataHandle>());
606 return; 584 return;
607 } 585 }
608 586
609 // Copy the entry pointer before passing it in base::Bind. 587 match_context->entry.reset(*entry_ptr);
610 disk_cache::Entry* tmp_entry_ptr = match_context->entry;
611 DCHECK(tmp_entry_ptr);
612
613 MetadataCallback headers_callback = base::Bind( 588 MetadataCallback headers_callback = base::Bind(
614 &CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(), 589 &CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(),
615 base::Passed(match_context.Pass())); 590 base::Passed(match_context.Pass()));
616 591
617 ReadMetadata(tmp_entry_ptr, headers_callback); 592 ReadMetadata(*entry_ptr, headers_callback);
618 } 593 }
619 594
620 void CacheStorageCache::MatchDidReadMetadata( 595 void CacheStorageCache::MatchDidReadMetadata(
621 scoped_ptr<MatchContext> match_context, 596 scoped_ptr<MatchContext> match_context,
622 scoped_ptr<CacheMetadata> metadata) { 597 scoped_ptr<CacheMetadata> metadata) {
623 if (!metadata) { 598 if (!metadata) {
624 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, 599 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
625 scoped_ptr<ServiceWorkerResponse>(), 600 scoped_ptr<ServiceWorkerResponse>(),
626 scoped_ptr<storage::BlobDataHandle>()); 601 scoped_ptr<storage::BlobDataHandle>());
627 return; 602 return;
628 } 603 }
629 604
630 match_context->response.reset(new ServiceWorkerResponse( 605 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse(
631 match_context->request->url, metadata->response().status_code(), 606 match_context->request->url, metadata->response().status_code(),
632 metadata->response().status_text(), 607 metadata->response().status_text(),
633 ProtoResponseTypeToWebResponseType(metadata->response().response_type()), 608 ProtoResponseTypeToWebResponseType(metadata->response().response_type()),
634 ServiceWorkerHeaderMap(), "", 0, GURL())); 609 ServiceWorkerHeaderMap(), "", 0, GURL()));
635 610
636 ServiceWorkerResponse* response = match_context->response.get();
637
638 if (metadata->response().has_url()) 611 if (metadata->response().has_url())
639 response->url = GURL(metadata->response().url()); 612 response->url = GURL(metadata->response().url());
640 613
641 for (int i = 0; i < metadata->response().headers_size(); ++i) { 614 for (int i = 0; i < metadata->response().headers_size(); ++i) {
642 const CacheHeaderMap header = metadata->response().headers(i); 615 const CacheHeaderMap header = metadata->response().headers(i);
643 DCHECK(header.name().find('\0') == std::string::npos); 616 DCHECK_EQ(std::string::npos, header.name().find('\0'));
644 DCHECK(header.value().find('\0') == std::string::npos); 617 DCHECK_EQ(std::string::npos, header.value().find('\0'));
645 response->headers.insert(std::make_pair(header.name(), header.value())); 618 response->headers.insert(std::make_pair(header.name(), header.value()));
646 } 619 }
647 620
648 ServiceWorkerHeaderMap cached_request_headers; 621 ServiceWorkerHeaderMap cached_request_headers;
649 for (int i = 0; i < metadata->request().headers_size(); ++i) { 622 for (int i = 0; i < metadata->request().headers_size(); ++i) {
650 const CacheHeaderMap header = metadata->request().headers(i); 623 const CacheHeaderMap header = metadata->request().headers(i);
651 DCHECK(header.name().find('\0') == std::string::npos); 624 DCHECK_EQ(std::string::npos, header.name().find('\0'));
652 DCHECK(header.value().find('\0') == std::string::npos); 625 DCHECK_EQ(std::string::npos, header.value().find('\0'));
653 cached_request_headers[header.name()] = header.value(); 626 cached_request_headers[header.name()] = header.value();
654 } 627 }
655 628
656 if (!VaryMatches(match_context->request->headers, cached_request_headers, 629 if (!VaryMatches(match_context->request->headers, cached_request_headers,
657 response->headers)) { 630 response->headers)) {
658 match_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, 631 match_context->original_callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
659 scoped_ptr<ServiceWorkerResponse>(), 632 scoped_ptr<ServiceWorkerResponse>(),
660 scoped_ptr<storage::BlobDataHandle>()); 633 scoped_ptr<storage::BlobDataHandle>());
661 return; 634 return;
662 } 635 }
663 636
664 if (match_context->entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { 637 if (match_context->entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
665 match_context->original_callback.Run(CACHE_STORAGE_OK, 638 match_context->original_callback.Run(CACHE_STORAGE_OK, response.Pass(),
666 match_context->response.Pass(),
667 scoped_ptr<storage::BlobDataHandle>()); 639 scoped_ptr<storage::BlobDataHandle>());
668 return; 640 return;
669 } 641 }
670 642
671 // Stream the response body into a blob. 643 if (!blob_storage_context_) {
672 if (!match_context->blob_storage_context) {
673 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, 644 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
674 scoped_ptr<ServiceWorkerResponse>(), 645 scoped_ptr<ServiceWorkerResponse>(),
675 scoped_ptr<storage::BlobDataHandle>()); 646 scoped_ptr<storage::BlobDataHandle>());
676 return; 647 return;
677 } 648 }
678 649
650 // Create a blob with the response body data.
651 response->blob_size = match_context->entry->GetDataSize(INDEX_RESPONSE_BODY);
679 response->blob_uuid = base::GenerateGUID(); 652 response->blob_uuid = base::GenerateGUID();
680 653 scoped_ptr<storage::BlobDataBuilder> blob_data(
681 match_context->blob_data.reset(
682 new storage::BlobDataBuilder(response->blob_uuid)); 654 new storage::BlobDataBuilder(response->blob_uuid));
683 match_context->response_body_buffer = new net::IOBufferWithSize(kBufferSize); 655 blob_data->AppendDiskCacheEntry(
684 656 match_context->entry.Pass(), INDEX_RESPONSE_BODY,
685 disk_cache::Entry* tmp_entry_ptr = match_context->entry; 657 make_scoped_ptr(new CacheStorageCacheExtraData(this)));
686 net::IOBufferWithSize* response_body_buffer =
687 match_context->response_body_buffer.get();
688
689 net::CompletionCallback read_callback = base::Bind(
690 &CacheStorageCache::MatchDidReadResponseBodyData,
691 weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass()));
692
693 int read_rv =
694 tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, 0, response_body_buffer,
695 response_body_buffer->size(), read_callback);
696
697 if (read_rv != net::ERR_IO_PENDING)
698 read_callback.Run(read_rv);
699 }
700
701 void CacheStorageCache::MatchDidReadResponseBodyData(
702 scoped_ptr<MatchContext> match_context,
703 int rv) {
704 if (rv < 0) {
705 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
706 scoped_ptr<ServiceWorkerResponse>(),
707 scoped_ptr<storage::BlobDataHandle>());
708 return;
709 }
710
711 if (rv == 0) {
712 match_context->response->blob_uuid = match_context->blob_data->uuid();
713 match_context->response->blob_size = match_context->total_bytes_read;
714 MatchDoneWithBody(match_context.Pass());
715 return;
716 }
717
718 // TODO(jkarlin): This copying of the the entire cache response into memory is
719 // awful. Create a new interface around SimpleCache that provides access the
720 // data directly from the file. See bug http://crbug.com/403493.
721 match_context->blob_data->AppendData(
722 match_context->response_body_buffer->data(), rv);
723 match_context->total_bytes_read += rv;
724 int total_bytes_read = match_context->total_bytes_read;
725
726 // Grab some pointers before passing match_context in bind.
727 net::IOBufferWithSize* buffer = match_context->response_body_buffer.get();
728 disk_cache::Entry* tmp_entry_ptr = match_context->entry;
729
730 net::CompletionCallback read_callback = base::Bind(
731 &CacheStorageCache::MatchDidReadResponseBodyData,
732 weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass()));
733
734 int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, total_bytes_read,
735 buffer, buffer->size(), read_callback);
736
737 if (read_rv != net::ERR_IO_PENDING)
738 read_callback.Run(read_rv);
739 }
740
741 void CacheStorageCache::MatchDoneWithBody(
742 scoped_ptr<MatchContext> match_context) {
743 if (!match_context->blob_storage_context) {
744 match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE,
745 scoped_ptr<ServiceWorkerResponse>(),
746 scoped_ptr<storage::BlobDataHandle>());
747 return;
748 }
749
750 scoped_ptr<storage::BlobDataHandle> blob_data_handle( 658 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
751 match_context->blob_storage_context->AddFinishedBlob( 659 blob_storage_context_->AddFinishedBlob(blob_data.get()));
752 match_context->blob_data.get())); 660 match_context->original_callback.Run(CACHE_STORAGE_OK, response.Pass(),
753
754 match_context->original_callback.Run(CACHE_STORAGE_OK,
755 match_context->response.Pass(),
756 blob_data_handle.Pass()); 661 blob_data_handle.Pass());
757 } 662 }
758 663
759 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, 664 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
760 const ErrorCallback& callback) { 665 const ErrorCallback& callback) {
761 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 666 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
762 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); 667 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type);
763 668
764 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest( 669 scoped_ptr<ServiceWorkerFetchRequest> request(new ServiceWorkerFetchRequest(
765 operation.request.url, operation.request.method, 670 operation.request.url, operation.request.method,
(...skipping 30 matching lines...) Expand all
796 scoped_ptr<PutContext> put_context(new PutContext( 701 scoped_ptr<PutContext> put_context(new PutContext(
797 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(), 702 origin_, request.Pass(), response.Pass(), blob_data_handle.Pass(),
798 pending_callback, request_context_, quota_manager_proxy_)); 703 pending_callback, request_context_, quota_manager_proxy_));
799 704
800 scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl, 705 scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::PutImpl,
801 weak_ptr_factory_.GetWeakPtr(), 706 weak_ptr_factory_.GetWeakPtr(),
802 base::Passed(put_context.Pass()))); 707 base::Passed(put_context.Pass())));
803 } 708 }
804 709
805 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) { 710 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) {
806 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 711 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
807 if (backend_state_ != BACKEND_OPEN) { 712 if (backend_state_ != BACKEND_OPEN) {
808 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 713 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
809 return; 714 return;
810 } 715 }
811 716
812 scoped_ptr<ServiceWorkerFetchRequest> request_copy( 717 scoped_ptr<ServiceWorkerFetchRequest> request_copy(
813 new ServiceWorkerFetchRequest(*put_context->request)); 718 new ServiceWorkerFetchRequest(*put_context->request));
814 719
815 DeleteImpl(request_copy.Pass(), base::Bind(&CacheStorageCache::PutDidDelete, 720 DeleteImpl(request_copy.Pass(), base::Bind(&CacheStorageCache::PutDidDelete,
816 weak_ptr_factory_.GetWeakPtr(), 721 weak_ptr_factory_.GetWeakPtr(),
817 base::Passed(put_context.Pass()))); 722 base::Passed(put_context.Pass())));
818 } 723 }
819 724
820 void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context, 725 void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context,
821 CacheStorageError delete_error) { 726 CacheStorageError delete_error) {
822 if (backend_state_ != BACKEND_OPEN) { 727 if (backend_state_ != BACKEND_OPEN) {
823 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 728 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
824 return; 729 return;
825 } 730 }
826 731
827 disk_cache::Entry** entry_ptr = &put_context->cache_entry; 732 scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*());
733 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
828 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 734 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
829 disk_cache::Backend* backend_ptr = backend_.get(); 735 disk_cache::Backend* backend_ptr = backend_.get();
830 736
831 net::CompletionCallback create_entry_callback = base::Bind( 737 net::CompletionCallback create_entry_callback = base::Bind(
832 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), 738 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
833 base::Passed(put_context.Pass())); 739 base::Passed(scoped_entry_ptr.Pass()), base::Passed(put_context.Pass()));
834 740
835 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, 741 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
836 create_entry_callback); 742 create_entry_callback);
837 743
838 if (create_rv != net::ERR_IO_PENDING) 744 if (create_rv != net::ERR_IO_PENDING)
839 create_entry_callback.Run(create_rv); 745 create_entry_callback.Run(create_rv);
840 } 746 }
841 747
842 void CacheStorageCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context, 748 void CacheStorageCache::PutDidCreateEntry(
843 int rv) { 749 scoped_ptr<disk_cache::Entry*> entry_ptr,
750 scoped_ptr<PutContext> put_context,
751 int rv) {
844 if (rv != net::OK) { 752 if (rv != net::OK) {
845 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS); 753 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS);
846 return; 754 return;
847 } 755 }
848 756 put_context->cache_entry.reset(*entry_ptr.get());
jkarlin 2015/05/29 14:59:41 reset(*entry_ptr)
gavinp 2015/05/29 18:06:07 Done.
849 DCHECK(put_context->cache_entry);
850 757
851 CacheMetadata metadata; 758 CacheMetadata metadata;
852 CacheRequest* request_metadata = metadata.mutable_request(); 759 CacheRequest* request_metadata = metadata.mutable_request();
853 request_metadata->set_method(put_context->request->method); 760 request_metadata->set_method(put_context->request->method);
854 for (ServiceWorkerHeaderMap::const_iterator it = 761 for (ServiceWorkerHeaderMap::const_iterator it =
855 put_context->request->headers.begin(); 762 put_context->request->headers.begin();
856 it != put_context->request->headers.end(); ++it) { 763 it != put_context->request->headers.end(); ++it) {
857 DCHECK(it->first.find('\0') == std::string::npos); 764 DCHECK(it->first.find('\0') == std::string::npos);
858 DCHECK(it->second.find('\0') == std::string::npos); 765 DCHECK(it->second.find('\0') == std::string::npos);
859 CacheHeaderMap* header_map = request_metadata->add_headers(); 766 CacheHeaderMap* header_map = request_metadata->add_headers();
(...skipping 20 matching lines...) Expand all
880 scoped_ptr<std::string> serialized(new std::string()); 787 scoped_ptr<std::string> serialized(new std::string());
881 if (!metadata.SerializeToString(serialized.get())) { 788 if (!metadata.SerializeToString(serialized.get())) {
882 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 789 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
883 return; 790 return;
884 } 791 }
885 792
886 scoped_refptr<net::StringIOBuffer> buffer( 793 scoped_refptr<net::StringIOBuffer> buffer(
887 new net::StringIOBuffer(serialized.Pass())); 794 new net::StringIOBuffer(serialized.Pass()));
888 795
889 // Get a temporary copy of the entry pointer before passing it in base::Bind. 796 // Get a temporary copy of the entry pointer before passing it in base::Bind.
890 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry; 797 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry.get();
891 798
892 net::CompletionCallback write_headers_callback = base::Bind( 799 net::CompletionCallback write_headers_callback = base::Bind(
893 &CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(), 800 &CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(),
894 base::Passed(put_context.Pass()), buffer->size()); 801 base::Passed(put_context.Pass()), buffer->size());
895 802
896 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(), 803 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(),
897 buffer->size(), write_headers_callback, 804 buffer->size(), write_headers_callback,
898 true /* truncate */); 805 true /* truncate */);
899 806
900 if (rv != net::ERR_IO_PENDING) 807 if (rv != net::ERR_IO_PENDING)
(...skipping 19 matching lines...) Expand all
920 storage::kStorageTypeTemporary, 827 storage::kStorageTypeTemporary,
921 put_context->cache_entry->GetDataSize(INDEX_HEADERS)); 828 put_context->cache_entry->GetDataSize(INDEX_HEADERS));
922 } 829 }
923 830
924 put_context->callback.Run(CACHE_STORAGE_OK); 831 put_context->callback.Run(CACHE_STORAGE_OK);
925 return; 832 return;
926 } 833 }
927 834
928 DCHECK(put_context->blob_data_handle); 835 DCHECK(put_context->blob_data_handle);
929 836
930 disk_cache::ScopedEntryPtr entry(put_context->cache_entry); 837 disk_cache::ScopedEntryPtr entry(put_context->cache_entry.Pass());
931 put_context->cache_entry = NULL;
932 scoped_ptr<BlobReader> reader(new BlobReader()); 838 scoped_ptr<BlobReader> reader(new BlobReader());
933 BlobReader* reader_ptr = reader.get(); 839 BlobReader* reader_ptr = reader.get();
934 840
935 // Grab some pointers before passing put_context in Bind. 841 // Grab some pointers before passing put_context in Bind.
936 net::URLRequestContext* request_context = put_context->request_context; 842 net::URLRequestContext* request_context = put_context->request_context;
937 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 843 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
938 put_context->blob_data_handle.Pass(); 844 put_context->blob_data_handle.Pass();
939 845
940 reader_ptr->StreamBlobToCache( 846 reader_ptr->StreamBlobToCache(
941 entry.Pass(), request_context, blob_data_handle.Pass(), 847 entry.Pass(), request_context, blob_data_handle.Pass(),
942 base::Bind(&CacheStorageCache::PutDidWriteBlobToCache, 848 base::Bind(&CacheStorageCache::PutDidWriteBlobToCache,
943 weak_ptr_factory_.GetWeakPtr(), 849 weak_ptr_factory_.GetWeakPtr(),
944 base::Passed(put_context.Pass()), 850 base::Passed(put_context.Pass()),
945 base::Passed(reader.Pass()))); 851 base::Passed(reader.Pass())));
946 } 852 }
947 853
948 void CacheStorageCache::PutDidWriteBlobToCache( 854 void CacheStorageCache::PutDidWriteBlobToCache(
949 scoped_ptr<PutContext> put_context, 855 scoped_ptr<PutContext> put_context,
950 scoped_ptr<BlobReader> blob_reader, 856 scoped_ptr<BlobReader> blob_reader,
951 disk_cache::ScopedEntryPtr entry, 857 disk_cache::ScopedEntryPtr entry,
952 bool success) { 858 bool success) {
953 DCHECK(entry); 859 DCHECK(entry);
954 put_context->cache_entry = entry.release(); 860 put_context->cache_entry = entry.Pass();
955 861
956 if (!success) { 862 if (!success) {
957 put_context->cache_entry->Doom(); 863 put_context->cache_entry->Doom();
958 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 864 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
959 return; 865 return;
960 } 866 }
961 867
962 if (put_context->quota_manager_proxy.get()) { 868 if (put_context->quota_manager_proxy.get()) {
963 put_context->quota_manager_proxy->NotifyStorageModified( 869 put_context->quota_manager_proxy->NotifyStorageModified(
964 storage::QuotaClient::kServiceWorkerCache, put_context->origin, 870 storage::QuotaClient::kServiceWorkerCache, put_context->origin,
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 CacheStorageError error, 1172 CacheStorageError error,
1267 scoped_ptr<Requests> requests) { 1173 scoped_ptr<Requests> requests) {
1268 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); 1174 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1269 1175
1270 callback.Run(error, requests.Pass()); 1176 callback.Run(error, requests.Pass());
1271 if (cache) 1177 if (cache)
1272 scheduler_->CompleteOperationAndRunNext(); 1178 scheduler_->CompleteOperationAndRunNext();
1273 } 1179 }
1274 1180
1275 } // namespace content 1181 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698