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

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: Created 5 years, 7 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/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/guid.h" 10 #include "base/guid.h"
(...skipping 12 matching lines...) Expand all
23 #include "storage/browser/blob/blob_data_handle.h" 23 #include "storage/browser/blob/blob_data_handle.h"
24 #include "storage/browser/blob/blob_storage_context.h" 24 #include "storage/browser/blob/blob_storage_context.h"
25 #include "storage/browser/blob/blob_url_request_job_factory.h" 25 #include "storage/browser/blob/blob_url_request_job_factory.h"
26 #include "storage/browser/quota/quota_manager_proxy.h" 26 #include "storage/browser/quota/quota_manager_proxy.h"
27 #include "third_party/WebKit/public/platform/WebServiceWorkerResponseType.h" 27 #include "third_party/WebKit/public/platform/WebServiceWorkerResponseType.h"
28 28
29 namespace content { 29 namespace content {
30 30
31 namespace { 31 namespace {
32 32
33 typedef base::Callback<void(bool)> BoolCallback;
34 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
35 EntryBoolCallback;
36 typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback;
37
38 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; 33 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY };
39 34
40 // The maximum size of an individual cache. Ultimately cache size is controlled 35 // The maximum size of an individual cache. Ultimately cache size is controlled
41 // per-origin. 36 // per-origin.
42 const int kMaxCacheBytes = 512 * 1024 * 1024; 37 const int kMaxCacheBytes = 512 * 1024 * 1024;
43 38
44 // Buffer size for cache and blob reading/writing. 39 // Buffer size for cache and blob reading/writing.
45 const int kBufferSize = 1024 * 512; 40 const int kBufferSize = 1024 * 512;
46 41
47 void NotReachedCompletionCallback(int rv) { 42 void NotReachedCompletionCallback(int rv) {
(...skipping 29 matching lines...) Expand all
77 return CacheResponse::DEFAULT_TYPE; 72 return CacheResponse::DEFAULT_TYPE;
78 case blink::WebServiceWorkerResponseTypeError: 73 case blink::WebServiceWorkerResponseTypeError:
79 return CacheResponse::ERROR_TYPE; 74 return CacheResponse::ERROR_TYPE;
80 case blink::WebServiceWorkerResponseTypeOpaque: 75 case blink::WebServiceWorkerResponseTypeOpaque:
81 return CacheResponse::OPAQUE_TYPE; 76 return CacheResponse::OPAQUE_TYPE;
82 } 77 }
83 NOTREACHED(); 78 NOTREACHED();
84 return CacheResponse::OPAQUE_TYPE; 79 return CacheResponse::OPAQUE_TYPE;
85 } 80 }
86 81
87 // Copy headers out of a cache entry and into a protobuf. The callback is
88 // guaranteed to be run.
89 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback);
90 void ReadMetadataDidReadMetadata(
91 disk_cache::Entry* entry,
92 const MetadataCallback& callback,
93 const scoped_refptr<net::IOBufferWithSize>& buffer,
94 int rv);
95
96 bool VaryMatches(const ServiceWorkerHeaderMap& request, 82 bool VaryMatches(const ServiceWorkerHeaderMap& request,
97 const ServiceWorkerHeaderMap& cached_request, 83 const ServiceWorkerHeaderMap& cached_request,
98 const ServiceWorkerHeaderMap& response) { 84 const ServiceWorkerHeaderMap& response) {
99 ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary"); 85 ServiceWorkerHeaderMap::const_iterator vary_iter = response.find("vary");
100 if (vary_iter == response.end()) 86 if (vary_iter == response.end())
101 return true; 87 return true;
102 88
103 std::vector<std::string> vary_keys; 89 std::vector<std::string> vary_keys;
104 Tokenize(vary_iter->second, ",", &vary_keys); 90 Tokenize(vary_iter->second, ",", &vary_keys);
105 for (std::vector<std::string>::const_iterator it = vary_keys.begin(); 91 for (std::vector<std::string>::const_iterator it = vary_keys.begin();
(...skipping 15 matching lines...) Expand all
121 // If the header exists in one, it exists in both. Verify that the values 107 // If the header exists in one, it exists in both. Verify that the values
122 // are equal. 108 // are equal.
123 if (request_iter != request.end() && 109 if (request_iter != request.end() &&
124 request_iter->second != cached_request_iter->second) 110 request_iter->second != cached_request_iter->second)
125 return false; 111 return false;
126 } 112 }
127 113
128 return true; 114 return true;
129 } 115 }
130 116
131 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) { 117 typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback;
132 DCHECK(entry);
133
134 scoped_refptr<net::IOBufferWithSize> buffer(
135 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
136
137 net::CompletionCallback read_header_callback =
138 base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer);
139
140 int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(),
141 read_header_callback);
142
143 if (read_rv != net::ERR_IO_PENDING)
144 read_header_callback.Run(read_rv);
145 }
146 118
147 void ReadMetadataDidReadMetadata( 119 void ReadMetadataDidReadMetadata(
148 disk_cache::Entry* entry, 120 disk_cache::Entry* entry,
149 const MetadataCallback& callback, 121 const MetadataCallback& callback,
150 const scoped_refptr<net::IOBufferWithSize>& buffer, 122 const scoped_refptr<net::IOBufferWithSize>& buffer,
151 int rv) { 123 int rv) {
152 if (rv != buffer->size()) { 124 if (rv != buffer->size()) {
153 callback.Run(scoped_ptr<CacheMetadata>()); 125 callback.Run(scoped_ptr<CacheMetadata>());
154 return; 126 return;
155 } 127 }
156 128
157 scoped_ptr<CacheMetadata> metadata(new CacheMetadata()); 129 scoped_ptr<CacheMetadata> metadata(new CacheMetadata());
158 130
159 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) { 131 if (!metadata->ParseFromArray(buffer->data(), buffer->size())) {
160 callback.Run(scoped_ptr<CacheMetadata>()); 132 callback.Run(scoped_ptr<CacheMetadata>());
161 return; 133 return;
162 } 134 }
163 135
164 callback.Run(metadata.Pass()); 136 callback.Run(metadata.Pass());
165 } 137 }
166 138
139 // Copy headers out of a cache entry and into a protobuf. The callback is
140 // guaranteed to be run.
141 void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) {
142 DCHECK(entry);
143
144 scoped_refptr<net::IOBufferWithSize> buffer(
145 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
146
147 net::CompletionCallback read_header_callback =
148 base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer);
149
150 int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(),
151 read_header_callback);
152
153 if (read_rv != net::ERR_IO_PENDING)
154 read_header_callback.Run(read_rv);
155 }
156
167 } // namespace 157 } // namespace
168 158
169 // Streams data from a blob and writes it to a given disk_cache::Entry. 159 // Streams data from a blob and writes it to a given disk_cache::Entry.
170 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate { 160 class CacheStorageCache::BlobReader : public net::URLRequest::Delegate {
171 public: 161 public:
172 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> 162 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
173 EntryAndBoolCallback; 163 EntryAndBoolCallback;
174 164
175 BlobReader() 165 BlobReader()
176 : cache_entry_offset_(0), 166 : cache_entry_offset_(0),
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 286
297 // Used for enumerating cache entries. 287 // Used for enumerating cache entries.
298 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator; 288 scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
299 disk_cache::Entry* enumerated_entry; 289 disk_cache::Entry* enumerated_entry;
300 290
301 DISALLOW_COPY_AND_ASSIGN(KeysContext); 291 DISALLOW_COPY_AND_ASSIGN(KeysContext);
302 }; 292 };
303 293
304 struct CacheStorageCache::MatchContext { 294 struct CacheStorageCache::MatchContext {
305 MatchContext(scoped_ptr<ServiceWorkerFetchRequest> request, 295 MatchContext(scoped_ptr<ServiceWorkerFetchRequest> request,
306 const CacheStorageCache::ResponseCallback& callback, 296 const CacheStorageCache::ResponseCallback& callback)
307 base::WeakPtr<storage::BlobStorageContext> blob_storage_context)
308 : request(request.Pass()), 297 : request(request.Pass()),
309 original_callback(callback), 298 original_callback(callback) {}
310 blob_storage_context(blob_storage_context),
311 entry(nullptr),
312 total_bytes_read(0) {}
313 299
314 ~MatchContext() {
315 if (entry)
316 entry->Close();
317 }
318
319 // Input
320 scoped_ptr<ServiceWorkerFetchRequest> request; 300 scoped_ptr<ServiceWorkerFetchRequest> request;
321 CacheStorageCache::ResponseCallback original_callback; 301 CacheStorageCache::ResponseCallback original_callback;
322 base::WeakPtr<storage::BlobStorageContext> blob_storage_context; 302 disk_cache::ScopedEntryPtr entry;
323 disk_cache::Entry* entry;
324
325 // Output
326 scoped_ptr<ServiceWorkerResponse> response;
327 scoped_ptr<storage::BlobDataBuilder> blob_data;
328
329 // For reading the cache entry data into a blob.
330 scoped_refptr<net::IOBufferWithSize> response_body_buffer;
331 size_t total_bytes_read;
332 303
333 DISALLOW_COPY_AND_ASSIGN(MatchContext); 304 DISALLOW_COPY_AND_ASSIGN(MatchContext);
334 }; 305 };
335 306
336 // The state needed to pass between CacheStorageCache::Put callbacks. 307 // The state needed to pass between CacheStorageCache::Put callbacks.
337 struct CacheStorageCache::PutContext { 308 struct CacheStorageCache::PutContext {
338 PutContext( 309 PutContext(
339 const GURL& origin, 310 const GURL& origin,
340 scoped_ptr<ServiceWorkerFetchRequest> request, 311 scoped_ptr<ServiceWorkerFetchRequest> request,
341 scoped_ptr<ServiceWorkerResponse> response, 312 scoped_ptr<ServiceWorkerResponse> response,
342 scoped_ptr<storage::BlobDataHandle> blob_data_handle, 313 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
343 const CacheStorageCache::ResponseCallback& callback, 314 const CacheStorageCache::ResponseCallback& callback,
344 net::URLRequestContext* request_context, 315 net::URLRequestContext* request_context,
345 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy) 316 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy)
346 : origin(origin), 317 : origin(origin),
347 request(request.Pass()), 318 request(request.Pass()),
348 response(response.Pass()), 319 response(response.Pass()),
349 blob_data_handle(blob_data_handle.Pass()), 320 blob_data_handle(blob_data_handle.Pass()),
350 callback(callback), 321 callback(callback),
351 request_context(request_context), 322 request_context(request_context),
352 quota_manager_proxy(quota_manager_proxy), 323 quota_manager_proxy(quota_manager_proxy) {}
353 cache_entry(NULL) {}
354 ~PutContext() {
355 if (cache_entry)
356 cache_entry->Close();
357 }
358 324
359 // Input parameters to the Put function. 325 // Input parameters to the Put function.
360 GURL origin; 326 GURL origin;
361 scoped_ptr<ServiceWorkerFetchRequest> request; 327 scoped_ptr<ServiceWorkerFetchRequest> request;
362 scoped_ptr<ServiceWorkerResponse> response; 328 scoped_ptr<ServiceWorkerResponse> response;
363 scoped_ptr<storage::BlobDataHandle> blob_data_handle; 329 scoped_ptr<storage::BlobDataHandle> blob_data_handle;
364 CacheStorageCache::ResponseCallback callback; 330 CacheStorageCache::ResponseCallback callback;
365 net::URLRequestContext* request_context; 331 net::URLRequestContext* request_context;
366 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy; 332 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy;
367 333 disk_cache::ScopedEntryPtr cache_entry;
368 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
369 // CreateEntry.
370 disk_cache::Entry* cache_entry;
371 334
372 // The BlobDataHandle for the output ServiceWorkerResponse. 335 // The BlobDataHandle for the output ServiceWorkerResponse.
373 scoped_ptr<storage::BlobDataHandle> out_blob_data_handle; 336 scoped_ptr<storage::BlobDataHandle> out_blob_data_handle;
374 337
375 DISALLOW_COPY_AND_ASSIGN(PutContext); 338 DISALLOW_COPY_AND_ASSIGN(PutContext);
376 }; 339 };
377 340
378 // static 341 // static
379 scoped_refptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( 342 scoped_refptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
380 const GURL& origin, 343 const GURL& origin,
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request, 537 void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request,
575 const ResponseCallback& callback) { 538 const ResponseCallback& callback) {
576 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 539 DCHECK(backend_state_ != BACKEND_UNINITIALIZED);
577 if (backend_state_ != BACKEND_OPEN) { 540 if (backend_state_ != BACKEND_OPEN) {
578 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<ServiceWorkerResponse>(), 541 callback.Run(ERROR_TYPE_STORAGE, scoped_ptr<ServiceWorkerResponse>(),
579 scoped_ptr<storage::BlobDataHandle>()); 542 scoped_ptr<storage::BlobDataHandle>());
580 return; 543 return;
581 } 544 }
582 545
583 scoped_ptr<MatchContext> match_context( 546 scoped_ptr<MatchContext> match_context(
584 new MatchContext(request.Pass(), callback, blob_storage_context_)); 547 new MatchContext(request.Pass(), callback));
585 548
586 disk_cache::Entry** entry_ptr = &match_context->entry; 549 scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*());
550 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
587 ServiceWorkerFetchRequest* request_ptr = match_context->request.get(); 551 ServiceWorkerFetchRequest* request_ptr = match_context->request.get();
588 552
589 net::CompletionCallback open_entry_callback = base::Bind( 553 net::CompletionCallback open_entry_callback = base::Bind(
590 &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), 554 &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(),
591 base::Passed(match_context.Pass())); 555 base::Passed(scoped_entry_ptr.Pass()), base::Passed(match_context.Pass())) ;
592 556
593 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr, 557 int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
594 open_entry_callback); 558 open_entry_callback);
595 if (rv != net::ERR_IO_PENDING) 559 if (rv != net::ERR_IO_PENDING)
596 open_entry_callback.Run(rv); 560 open_entry_callback.Run(rv);
597 } 561 }
598 562
599 void CacheStorageCache::MatchDidOpenEntry( 563 void CacheStorageCache::MatchDidOpenEntry(
564 scoped_ptr<disk_cache::Entry*> entry_ptr,
600 scoped_ptr<MatchContext> match_context, 565 scoped_ptr<MatchContext> match_context,
601 int rv) { 566 int rv) {
602 if (rv != net::OK) { 567 if (rv != net::OK) {
603 match_context->original_callback.Run( 568 match_context->original_callback.Run(
604 CacheStorageCache::ERROR_TYPE_NOT_FOUND, 569 CacheStorageCache::ERROR_TYPE_NOT_FOUND,
605 scoped_ptr<ServiceWorkerResponse>(), 570 scoped_ptr<ServiceWorkerResponse>(),
606 scoped_ptr<storage::BlobDataHandle>()); 571 scoped_ptr<storage::BlobDataHandle>());
607 return; 572 return;
608 } 573 }
609 574
610 // Copy the entry pointer before passing it in base::Bind. 575 match_context->entry.reset(*entry_ptr);
611 disk_cache::Entry* tmp_entry_ptr = match_context->entry;
612 DCHECK(tmp_entry_ptr);
613
614 MetadataCallback headers_callback = base::Bind( 576 MetadataCallback headers_callback = base::Bind(
615 &CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(), 577 &CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(),
616 base::Passed(match_context.Pass())); 578 base::Passed(match_context.Pass()));
617 579
618 ReadMetadata(tmp_entry_ptr, headers_callback); 580 ReadMetadata(*entry_ptr, headers_callback);
619 } 581 }
620 582
621 void CacheStorageCache::MatchDidReadMetadata( 583 void CacheStorageCache::MatchDidReadMetadata(
622 scoped_ptr<MatchContext> match_context, 584 scoped_ptr<MatchContext> match_context,
623 scoped_ptr<CacheMetadata> metadata) { 585 scoped_ptr<CacheMetadata> metadata) {
624 if (!metadata) { 586 if (!metadata) {
625 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE, 587 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
626 scoped_ptr<ServiceWorkerResponse>(), 588 scoped_ptr<ServiceWorkerResponse>(),
627 scoped_ptr<storage::BlobDataHandle>()); 589 scoped_ptr<storage::BlobDataHandle>());
628 return; 590 return;
629 } 591 }
630 592
631 match_context->response.reset(new ServiceWorkerResponse( 593 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse(
632 match_context->request->url, metadata->response().status_code(), 594 match_context->request->url, metadata->response().status_code(),
633 metadata->response().status_text(), 595 metadata->response().status_text(),
634 ProtoResponseTypeToWebResponseType(metadata->response().response_type()), 596 ProtoResponseTypeToWebResponseType(metadata->response().response_type()),
635 ServiceWorkerHeaderMap(), "", 0, GURL())); 597 ServiceWorkerHeaderMap(), "", 0, GURL()));
636 598
637 ServiceWorkerResponse* response = match_context->response.get();
638
639 if (metadata->response().has_url()) 599 if (metadata->response().has_url())
640 response->url = GURL(metadata->response().url()); 600 response->url = GURL(metadata->response().url());
641 601
642 for (int i = 0; i < metadata->response().headers_size(); ++i) { 602 for (int i = 0; i < metadata->response().headers_size(); ++i) {
643 const CacheHeaderMap header = metadata->response().headers(i); 603 const CacheHeaderMap header = metadata->response().headers(i);
644 DCHECK(header.name().find('\0') == std::string::npos); 604 DCHECK_EQ(std::string::npos, header.name().find('\0'));
645 DCHECK(header.value().find('\0') == std::string::npos); 605 DCHECK_EQ(std::string::npos, header.value().find('\0'));
646 response->headers.insert(std::make_pair(header.name(), header.value())); 606 response->headers.insert(std::make_pair(header.name(), header.value()));
647 } 607 }
648 608
649 ServiceWorkerHeaderMap cached_request_headers; 609 ServiceWorkerHeaderMap cached_request_headers;
650 for (int i = 0; i < metadata->request().headers_size(); ++i) { 610 for (int i = 0; i < metadata->request().headers_size(); ++i) {
651 const CacheHeaderMap header = metadata->request().headers(i); 611 const CacheHeaderMap header = metadata->request().headers(i);
652 DCHECK(header.name().find('\0') == std::string::npos); 612 DCHECK_EQ(std::string::npos, header.name().find('\0'));
653 DCHECK(header.value().find('\0') == std::string::npos); 613 DCHECK_EQ(std::string::npos, header.value().find('\0'));
654 cached_request_headers[header.name()] = header.value(); 614 cached_request_headers[header.name()] = header.value();
655 } 615 }
656 616
657 if (!VaryMatches(match_context->request->headers, cached_request_headers, 617 if (!VaryMatches(match_context->request->headers, cached_request_headers,
658 response->headers)) { 618 response->headers)) {
659 match_context->original_callback.Run( 619 match_context->original_callback.Run(
660 CacheStorageCache::ERROR_TYPE_NOT_FOUND, 620 CacheStorageCache::ERROR_TYPE_NOT_FOUND,
661 scoped_ptr<ServiceWorkerResponse>(), 621 scoped_ptr<ServiceWorkerResponse>(),
662 scoped_ptr<storage::BlobDataHandle>()); 622 scoped_ptr<storage::BlobDataHandle>());
663 return; 623 return;
664 } 624 }
665 625
666 if (match_context->entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { 626 if (match_context->entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
667 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK, 627 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK,
668 match_context->response.Pass(), 628 response.Pass(),
669 scoped_ptr<storage::BlobDataHandle>()); 629 scoped_ptr<storage::BlobDataHandle>());
670 return; 630 return;
671 } 631 }
672 632
673 // Stream the response body into a blob. 633 if (!blob_storage_context_) {
674 if (!match_context->blob_storage_context) {
675 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE, 634 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
676 scoped_ptr<ServiceWorkerResponse>(), 635 scoped_ptr<ServiceWorkerResponse>(),
677 scoped_ptr<storage::BlobDataHandle>()); 636 scoped_ptr<storage::BlobDataHandle>());
678 return; 637 return;
679 } 638 }
680 639
640 // Create a blob with the response body data.
681 response->blob_uuid = base::GenerateGUID(); 641 response->blob_uuid = base::GenerateGUID();
682 642 scoped_ptr<storage::BlobDataBuilder> blob_data(
michaeln 2015/06/12 22:35:09 looks like BlobDataBuilder could be stack allocate
gavinp 2015/06/15 14:01:19 Done.
683 match_context->blob_data.reset(
684 new storage::BlobDataBuilder(response->blob_uuid)); 643 new storage::BlobDataBuilder(response->blob_uuid));
685 match_context->response_body_buffer = new net::IOBufferWithSize(kBufferSize); 644 blob_data->AppendDiskCacheEntry(match_context->entry.Pass(),
686 645 INDEX_RESPONSE_BODY);
687 disk_cache::Entry* tmp_entry_ptr = match_context->entry;
688 net::IOBufferWithSize* response_body_buffer =
689 match_context->response_body_buffer.get();
690
691 net::CompletionCallback read_callback = base::Bind(
692 &CacheStorageCache::MatchDidReadResponseBodyData,
693 weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass()));
694
695 int read_rv =
696 tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, 0, response_body_buffer,
697 response_body_buffer->size(), read_callback);
698
699 if (read_rv != net::ERR_IO_PENDING)
700 read_callback.Run(read_rv);
701 }
702
703 void CacheStorageCache::MatchDidReadResponseBodyData(
704 scoped_ptr<MatchContext> match_context,
705 int rv) {
706 if (rv < 0) {
707 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
708 scoped_ptr<ServiceWorkerResponse>(),
709 scoped_ptr<storage::BlobDataHandle>());
710 return;
711 }
712
713 if (rv == 0) {
714 match_context->response->blob_uuid = match_context->blob_data->uuid();
715 match_context->response->blob_size = match_context->total_bytes_read;
716 MatchDoneWithBody(match_context.Pass());
717 return;
718 }
719
720 // TODO(jkarlin): This copying of the the entire cache response into memory is
721 // awful. Create a new interface around SimpleCache that provides access the
722 // data directly from the file. See bug http://crbug.com/403493.
723 match_context->blob_data->AppendData(
724 match_context->response_body_buffer->data(), rv);
725 match_context->total_bytes_read += rv;
726 int total_bytes_read = match_context->total_bytes_read;
727
728 // Grab some pointers before passing match_context in bind.
729 net::IOBufferWithSize* buffer = match_context->response_body_buffer.get();
730 disk_cache::Entry* tmp_entry_ptr = match_context->entry;
731
732 net::CompletionCallback read_callback = base::Bind(
733 &CacheStorageCache::MatchDidReadResponseBodyData,
734 weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass()));
735
736 int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, total_bytes_read,
737 buffer, buffer->size(), read_callback);
738
739 if (read_rv != net::ERR_IO_PENDING)
740 read_callback.Run(read_rv);
741 }
742
743 void CacheStorageCache::MatchDoneWithBody(
744 scoped_ptr<MatchContext> match_context) {
745 if (!match_context->blob_storage_context) {
746 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
747 scoped_ptr<ServiceWorkerResponse>(),
748 scoped_ptr<storage::BlobDataHandle>());
749 return;
750 }
751
752 scoped_ptr<storage::BlobDataHandle> blob_data_handle( 646 scoped_ptr<storage::BlobDataHandle> blob_data_handle(
753 match_context->blob_storage_context->AddFinishedBlob( 647 blob_storage_context_->AddFinishedBlob(blob_data.get()));
754 match_context->blob_data.get()));
755
756 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK, 648 match_context->original_callback.Run(CacheStorageCache::ERROR_TYPE_OK,
757 match_context->response.Pass(), 649 response.Pass(),
758 blob_data_handle.Pass()); 650 blob_data_handle.Pass());
759 } 651 }
760 652
761 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) { 653 void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) {
762 DCHECK(backend_state_ != BACKEND_UNINITIALIZED); 654 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
763 if (backend_state_ != BACKEND_OPEN) { 655 if (backend_state_ != BACKEND_OPEN) {
764 put_context->callback.Run(ERROR_TYPE_STORAGE, 656 put_context->callback.Run(ERROR_TYPE_STORAGE,
765 scoped_ptr<ServiceWorkerResponse>(), 657 scoped_ptr<ServiceWorkerResponse>(),
766 scoped_ptr<storage::BlobDataHandle>()); 658 scoped_ptr<storage::BlobDataHandle>());
767 return; 659 return;
768 } 660 }
769 661
770 scoped_ptr<ServiceWorkerFetchRequest> request_copy( 662 scoped_ptr<ServiceWorkerFetchRequest> request_copy(
771 new ServiceWorkerFetchRequest(*put_context->request)); 663 new ServiceWorkerFetchRequest(*put_context->request));
772 664
773 DeleteImpl(request_copy.Pass(), base::Bind(&CacheStorageCache::PutDidDelete, 665 DeleteImpl(request_copy.Pass(), base::Bind(&CacheStorageCache::PutDidDelete,
774 weak_ptr_factory_.GetWeakPtr(), 666 weak_ptr_factory_.GetWeakPtr(),
775 base::Passed(put_context.Pass()))); 667 base::Passed(put_context.Pass())));
776 } 668 }
777 669
778 void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context, 670 void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context,
779 ErrorType delete_error) { 671 ErrorType delete_error) {
780 if (backend_state_ != BACKEND_OPEN) { 672 if (backend_state_ != BACKEND_OPEN) {
781 put_context->callback.Run(ERROR_TYPE_STORAGE, 673 put_context->callback.Run(ERROR_TYPE_STORAGE,
782 scoped_ptr<ServiceWorkerResponse>(), 674 scoped_ptr<ServiceWorkerResponse>(),
783 scoped_ptr<storage::BlobDataHandle>()); 675 scoped_ptr<storage::BlobDataHandle>());
784 return; 676 return;
785 } 677 }
786 678
787 disk_cache::Entry** entry_ptr = &put_context->cache_entry; 679 scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*());
680 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
788 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 681 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
789 disk_cache::Backend* backend_ptr = backend_.get(); 682 disk_cache::Backend* backend_ptr = backend_.get();
790 683
791 net::CompletionCallback create_entry_callback = base::Bind( 684 net::CompletionCallback create_entry_callback = base::Bind(
792 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), 685 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
793 base::Passed(put_context.Pass())); 686 base::Passed(scoped_entry_ptr.Pass()), base::Passed(put_context.Pass()));
794 687
795 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, 688 int create_rv = backend_ptr->CreateEntry(
796 create_entry_callback); 689 request_ptr->url.spec(), entry_ptr, create_entry_callback);
797 690
798 if (create_rv != net::ERR_IO_PENDING) 691 if (create_rv != net::ERR_IO_PENDING)
799 create_entry_callback.Run(create_rv); 692 create_entry_callback.Run(create_rv);
800 } 693 }
801 694
802 void CacheStorageCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context, 695 void CacheStorageCache::PutDidCreateEntry(scoped_ptr<disk_cache::Entry*> entry_p tr,
696 scoped_ptr<PutContext> put_context,
803 int rv) { 697 int rv) {
804 if (rv != net::OK) { 698 if (rv != net::OK) {
805 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_EXISTS, 699 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_EXISTS,
806 scoped_ptr<ServiceWorkerResponse>(), 700 scoped_ptr<ServiceWorkerResponse>(),
807 scoped_ptr<storage::BlobDataHandle>()); 701 scoped_ptr<storage::BlobDataHandle>());
808 return; 702 return;
809 } 703 }
810 704 put_context->cache_entry.reset(*entry_ptr.get());
811 DCHECK(put_context->cache_entry);
812 705
813 CacheMetadata metadata; 706 CacheMetadata metadata;
814 CacheRequest* request_metadata = metadata.mutable_request(); 707 CacheRequest* request_metadata = metadata.mutable_request();
815 request_metadata->set_method(put_context->request->method); 708 request_metadata->set_method(put_context->request->method);
816 for (ServiceWorkerHeaderMap::const_iterator it = 709 for (ServiceWorkerHeaderMap::const_iterator it =
817 put_context->request->headers.begin(); 710 put_context->request->headers.begin();
818 it != put_context->request->headers.end(); ++it) { 711 it != put_context->request->headers.end(); ++it) {
819 DCHECK(it->first.find('\0') == std::string::npos); 712 DCHECK(it->first.find('\0') == std::string::npos);
820 DCHECK(it->second.find('\0') == std::string::npos); 713 DCHECK(it->second.find('\0') == std::string::npos);
821 CacheHeaderMap* header_map = request_metadata->add_headers(); 714 CacheHeaderMap* header_map = request_metadata->add_headers();
(...skipping 22 matching lines...) Expand all
844 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE, 737 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
845 scoped_ptr<ServiceWorkerResponse>(), 738 scoped_ptr<ServiceWorkerResponse>(),
846 scoped_ptr<storage::BlobDataHandle>()); 739 scoped_ptr<storage::BlobDataHandle>());
847 return; 740 return;
848 } 741 }
849 742
850 scoped_refptr<net::StringIOBuffer> buffer( 743 scoped_refptr<net::StringIOBuffer> buffer(
851 new net::StringIOBuffer(serialized.Pass())); 744 new net::StringIOBuffer(serialized.Pass()));
852 745
853 // Get a temporary copy of the entry pointer before passing it in base::Bind. 746 // Get a temporary copy of the entry pointer before passing it in base::Bind.
854 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry; 747 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry.get();
855 748
856 net::CompletionCallback write_headers_callback = base::Bind( 749 net::CompletionCallback write_headers_callback = base::Bind(
857 &CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(), 750 &CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(),
858 base::Passed(put_context.Pass()), buffer->size()); 751 base::Passed(put_context.Pass()), buffer->size());
859 752
860 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(), 753 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(),
861 buffer->size(), write_headers_callback, 754 buffer->size(), write_headers_callback,
862 true /* truncate */); 755 true /* truncate */);
863 756
864 if (rv != net::ERR_IO_PENDING) 757 if (rv != net::ERR_IO_PENDING)
(...skipping 23 matching lines...) Expand all
888 } 781 }
889 782
890 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_OK, 783 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_OK,
891 put_context->response.Pass(), 784 put_context->response.Pass(),
892 scoped_ptr<storage::BlobDataHandle>()); 785 scoped_ptr<storage::BlobDataHandle>());
893 return; 786 return;
894 } 787 }
895 788
896 DCHECK(put_context->blob_data_handle); 789 DCHECK(put_context->blob_data_handle);
897 790
898 disk_cache::ScopedEntryPtr entry(put_context->cache_entry); 791 disk_cache::ScopedEntryPtr entry(put_context->cache_entry.Pass());
899 put_context->cache_entry = NULL;
900 scoped_ptr<BlobReader> reader(new BlobReader()); 792 scoped_ptr<BlobReader> reader(new BlobReader());
901 BlobReader* reader_ptr = reader.get(); 793 BlobReader* reader_ptr = reader.get();
902 794
903 // Grab some pointers before passing put_context in Bind. 795 // Grab some pointers before passing put_context in Bind.
904 net::URLRequestContext* request_context = put_context->request_context; 796 net::URLRequestContext* request_context = put_context->request_context;
905 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 797 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
906 put_context->blob_data_handle.Pass(); 798 put_context->blob_data_handle.Pass();
907 799
908 reader_ptr->StreamBlobToCache( 800 reader_ptr->StreamBlobToCache(
909 entry.Pass(), request_context, blob_data_handle.Pass(), 801 entry.Pass(), request_context, blob_data_handle.Pass(),
910 base::Bind(&CacheStorageCache::PutDidWriteBlobToCache, 802 base::Bind(&CacheStorageCache::PutDidWriteBlobToCache,
911 weak_ptr_factory_.GetWeakPtr(), 803 weak_ptr_factory_.GetWeakPtr(),
912 base::Passed(put_context.Pass()), 804 base::Passed(put_context.Pass()),
913 base::Passed(reader.Pass()))); 805 base::Passed(reader.Pass())));
914 } 806 }
915 807
916 void CacheStorageCache::PutDidWriteBlobToCache( 808 void CacheStorageCache::PutDidWriteBlobToCache(
917 scoped_ptr<PutContext> put_context, 809 scoped_ptr<PutContext> put_context,
918 scoped_ptr<BlobReader> blob_reader, 810 scoped_ptr<BlobReader> blob_reader,
919 disk_cache::ScopedEntryPtr entry, 811 disk_cache::ScopedEntryPtr entry,
920 bool success) { 812 bool success) {
921 DCHECK(entry); 813 DCHECK(entry);
922 put_context->cache_entry = entry.release(); 814 put_context->cache_entry = entry.Pass();
923 815
924 if (!success) { 816 if (!success) {
925 put_context->cache_entry->Doom(); 817 put_context->cache_entry->Doom();
926 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE, 818 put_context->callback.Run(CacheStorageCache::ERROR_TYPE_STORAGE,
927 scoped_ptr<ServiceWorkerResponse>(), 819 scoped_ptr<ServiceWorkerResponse>(),
928 scoped_ptr<storage::BlobDataHandle>()); 820 scoped_ptr<storage::BlobDataHandle>());
929 return; 821 return;
930 } 822 }
931 823
932 if (put_context->quota_manager_proxy.get()) { 824 if (put_context->quota_manager_proxy.get()) {
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 ErrorType error, 1111 ErrorType error,
1220 scoped_ptr<Requests> requests) { 1112 scoped_ptr<Requests> requests) {
1221 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr(); 1113 base::WeakPtr<CacheStorageCache> cache = weak_ptr_factory_.GetWeakPtr();
1222 1114
1223 callback.Run(error, requests.Pass()); 1115 callback.Run(error, requests.Pass());
1224 if (cache) 1116 if (cache)
1225 scheduler_->CompleteOperationAndRunNext(); 1117 scheduler_->CompleteOperationAndRunNext();
1226 } 1118 }
1227 1119
1228 } // namespace content 1120 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698