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

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

Powered by Google App Engine
This is Rietveld 408576698