| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_cache.h" | 5 #include "content/browser/service_worker/service_worker_cache.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/guid.h" | 10 #include "base/guid.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 BoolCallback callback_; | 159 BoolCallback callback_; |
| 160 scoped_refptr<net::IOBufferWithSize> buffer_; | 160 scoped_refptr<net::IOBufferWithSize> buffer_; |
| 161 base::WeakPtrFactory<BlobReader> weak_ptr_factory_; | 161 base::WeakPtrFactory<BlobReader> weak_ptr_factory_; |
| 162 }; | 162 }; |
| 163 | 163 |
| 164 // The state needed to pass between ServiceWorkerCache::Put callbacks. | 164 // The state needed to pass between ServiceWorkerCache::Put callbacks. |
| 165 struct PutContext { | 165 struct PutContext { |
| 166 PutContext(scoped_ptr<ServiceWorkerFetchRequest> request, | 166 PutContext(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 167 scoped_ptr<ServiceWorkerResponse> response, | 167 scoped_ptr<ServiceWorkerResponse> response, |
| 168 scoped_ptr<storage::BlobDataHandle> blob_data_handle, | 168 scoped_ptr<storage::BlobDataHandle> blob_data_handle, |
| 169 const ServiceWorkerCache::ErrorCallback& callback, | 169 const ServiceWorkerCache::ResponseCallback& callback, |
| 170 net::URLRequestContext* request_context) | 170 net::URLRequestContext* request_context) |
| 171 : request(request.Pass()), | 171 : request(request.Pass()), |
| 172 response(response.Pass()), | 172 response(response.Pass()), |
| 173 blob_data_handle(blob_data_handle.Pass()), | 173 blob_data_handle(blob_data_handle.Pass()), |
| 174 callback(callback), | 174 callback(callback), |
| 175 request_context(request_context), | 175 request_context(request_context), |
| 176 cache_entry(NULL) {} | 176 cache_entry(NULL) {} |
| 177 ~PutContext() { | 177 ~PutContext() { |
| 178 if (cache_entry) | 178 if (cache_entry) |
| 179 cache_entry->Close(); | 179 cache_entry->Close(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 // Input parameters to the Put function. | 182 // Input parameters to the Put function. |
| 183 scoped_ptr<ServiceWorkerFetchRequest> request; | 183 scoped_ptr<ServiceWorkerFetchRequest> request; |
| 184 scoped_ptr<ServiceWorkerResponse> response; | 184 scoped_ptr<ServiceWorkerResponse> response; |
| 185 scoped_ptr<storage::BlobDataHandle> blob_data_handle; | 185 scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
| 186 ServiceWorkerCache::ErrorCallback callback; | 186 ServiceWorkerCache::ResponseCallback callback; |
| 187 | 187 |
| 188 net::URLRequestContext* request_context; | 188 net::URLRequestContext* request_context; |
| 189 | 189 |
| 190 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to | 190 // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to |
| 191 // CreateEntry. | 191 // CreateEntry. |
| 192 disk_cache::Entry* cache_entry; | 192 disk_cache::Entry* cache_entry; |
| 193 | 193 |
| 194 // The BlobDataHandle for the output ServiceWorkerResponse. |
| 195 scoped_ptr<storage::BlobDataHandle> out_blob_data_handle; |
| 196 |
| 194 DISALLOW_COPY_AND_ASSIGN(PutContext); | 197 DISALLOW_COPY_AND_ASSIGN(PutContext); |
| 195 }; | 198 }; |
| 196 | 199 |
| 197 // Put callbacks | 200 // Put callbacks |
| 198 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv); | 201 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv); |
| 199 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context, | 202 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context, |
| 200 int expected_bytes, | 203 int expected_bytes, |
| 201 int rv); | 204 int rv); |
| 202 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context, | 205 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context, |
| 203 scoped_ptr<BlobReader> blob_reader, | 206 scoped_ptr<BlobReader> blob_reader, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 int rv); | 248 int rv); |
| 246 | 249 |
| 247 // CreateBackend callbacks | 250 // CreateBackend callbacks |
| 248 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, | 251 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, |
| 249 scoped_ptr<ScopedBackendPtr> backend_ptr, | 252 scoped_ptr<ScopedBackendPtr> backend_ptr, |
| 250 base::WeakPtr<ServiceWorkerCache> cache, | 253 base::WeakPtr<ServiceWorkerCache> cache, |
| 251 int rv); | 254 int rv); |
| 252 | 255 |
| 253 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv) { | 256 void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv) { |
| 254 if (rv != net::OK) { | 257 if (rv != net::OK) { |
| 255 put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists); | 258 put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists, |
| 259 scoped_ptr<ServiceWorkerResponse>(), |
| 260 scoped_ptr<storage::BlobDataHandle>()); |
| 256 return; | 261 return; |
| 257 } | 262 } |
| 258 | 263 |
| 259 DCHECK(put_context->cache_entry); | 264 DCHECK(put_context->cache_entry); |
| 260 | 265 |
| 261 ServiceWorkerRequestResponseHeaders headers; | 266 ServiceWorkerRequestResponseHeaders headers; |
| 262 headers.set_method(put_context->request->method); | 267 headers.set_method(put_context->request->method); |
| 263 | 268 |
| 264 headers.set_status_code(put_context->response->status_code); | 269 headers.set_status_code(put_context->response->status_code); |
| 265 headers.set_status_text(put_context->response->status_text); | 270 headers.set_status_text(put_context->response->status_text); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 278 it != put_context->response->headers.end(); | 283 it != put_context->response->headers.end(); |
| 279 ++it) { | 284 ++it) { |
| 280 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = | 285 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = |
| 281 headers.add_response_headers(); | 286 headers.add_response_headers(); |
| 282 header_map->set_name(it->first); | 287 header_map->set_name(it->first); |
| 283 header_map->set_value(it->second); | 288 header_map->set_value(it->second); |
| 284 } | 289 } |
| 285 | 290 |
| 286 scoped_ptr<std::string> serialized(new std::string()); | 291 scoped_ptr<std::string> serialized(new std::string()); |
| 287 if (!headers.SerializeToString(serialized.get())) { | 292 if (!headers.SerializeToString(serialized.get())) { |
| 288 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 293 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 294 scoped_ptr<ServiceWorkerResponse>(), |
| 295 scoped_ptr<storage::BlobDataHandle>()); |
| 289 return; | 296 return; |
| 290 } | 297 } |
| 291 | 298 |
| 292 scoped_refptr<net::StringIOBuffer> buffer( | 299 scoped_refptr<net::StringIOBuffer> buffer( |
| 293 new net::StringIOBuffer(serialized.Pass())); | 300 new net::StringIOBuffer(serialized.Pass())); |
| 294 | 301 |
| 295 // Get a temporary copy of the entry pointer before passing it in base::Bind. | 302 // Get a temporary copy of the entry pointer before passing it in base::Bind. |
| 296 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry; | 303 disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry; |
| 297 | 304 |
| 298 net::CompletionCallback write_headers_callback = base::Bind( | 305 net::CompletionCallback write_headers_callback = base::Bind( |
| 299 PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size()); | 306 PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size()); |
| 300 | 307 |
| 301 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, | 308 rv = tmp_entry_ptr->WriteData(INDEX_HEADERS, |
| 302 0 /* offset */, | 309 0 /* offset */, |
| 303 buffer.get(), | 310 buffer.get(), |
| 304 buffer->size(), | 311 buffer->size(), |
| 305 write_headers_callback, | 312 write_headers_callback, |
| 306 true /* truncate */); | 313 true /* truncate */); |
| 307 | 314 |
| 308 if (rv != net::ERR_IO_PENDING) | 315 if (rv != net::ERR_IO_PENDING) |
| 309 write_headers_callback.Run(rv); | 316 write_headers_callback.Run(rv); |
| 310 } | 317 } |
| 311 | 318 |
| 312 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context, | 319 void PutDidWriteHeaders(scoped_ptr<PutContext> put_context, |
| 313 int expected_bytes, | 320 int expected_bytes, |
| 314 int rv) { | 321 int rv) { |
| 315 if (rv != expected_bytes) { | 322 if (rv != expected_bytes) { |
| 316 put_context->cache_entry->Doom(); | 323 put_context->cache_entry->Doom(); |
| 317 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 324 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 325 scoped_ptr<ServiceWorkerResponse>(), |
| 326 scoped_ptr<storage::BlobDataHandle>()); |
| 318 return; | 327 return; |
| 319 } | 328 } |
| 320 | 329 |
| 321 // The metadata is written, now for the response content. The data is streamed | 330 // The metadata is written, now for the response content. The data is streamed |
| 322 // from the blob into the cache entry. | 331 // from the blob into the cache entry. |
| 323 | 332 |
| 324 if (put_context->response->blob_uuid.empty()) { | 333 if (put_context->response->blob_uuid.empty()) { |
| 325 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK); | 334 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 335 put_context->response.Pass(), |
| 336 scoped_ptr<storage::BlobDataHandle>()); |
| 326 return; | 337 return; |
| 327 } | 338 } |
| 328 | 339 |
| 329 DCHECK(put_context->blob_data_handle); | 340 DCHECK(put_context->blob_data_handle); |
| 330 | 341 |
| 331 disk_cache::ScopedEntryPtr entry(put_context->cache_entry); | 342 disk_cache::ScopedEntryPtr entry(put_context->cache_entry); |
| 332 put_context->cache_entry = NULL; | 343 put_context->cache_entry = NULL; |
| 333 scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass())); | 344 scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass())); |
| 334 | 345 |
| 335 BlobReader* reader_ptr = reader.get(); | 346 BlobReader* reader_ptr = reader.get(); |
| 336 | 347 |
| 337 // Grab some pointers before passing put_context in Bind. | 348 // Grab some pointers before passing put_context in Bind. |
| 338 net::URLRequestContext* request_context = put_context->request_context; | 349 net::URLRequestContext* request_context = put_context->request_context; |
| 339 scoped_ptr<storage::BlobDataHandle> blob_data_handle = | 350 scoped_ptr<storage::BlobDataHandle> blob_data_handle = |
| 340 put_context->blob_data_handle.Pass(); | 351 put_context->blob_data_handle.Pass(); |
| 341 | 352 |
| 342 reader_ptr->StreamBlobToCache(request_context, | 353 reader_ptr->StreamBlobToCache(request_context, |
| 343 blob_data_handle.Pass(), | 354 blob_data_handle.Pass(), |
| 344 base::Bind(PutDidWriteBlobToCache, | 355 base::Bind(PutDidWriteBlobToCache, |
| 345 base::Passed(put_context.Pass()), | 356 base::Passed(put_context.Pass()), |
| 346 base::Passed(reader.Pass()))); | 357 base::Passed(reader.Pass()))); |
| 347 } | 358 } |
| 348 | 359 |
| 349 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context, | 360 void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context, |
| 350 scoped_ptr<BlobReader> blob_reader, | 361 scoped_ptr<BlobReader> blob_reader, |
| 351 bool success) { | 362 bool success) { |
| 352 if (!success) { | 363 if (!success) { |
| 353 put_context->cache_entry->Doom(); | 364 put_context->cache_entry->Doom(); |
| 354 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 365 put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 366 scoped_ptr<ServiceWorkerResponse>(), |
| 367 scoped_ptr<storage::BlobDataHandle>()); |
| 355 return; | 368 return; |
| 356 } | 369 } |
| 357 | 370 |
| 358 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK); | 371 put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 372 put_context->response.Pass(), |
| 373 put_context->out_blob_data_handle.Pass()); |
| 359 } | 374 } |
| 360 | 375 |
| 361 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, | 376 void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 362 const ServiceWorkerCache::ResponseCallback& callback, | 377 const ServiceWorkerCache::ResponseCallback& callback, |
| 363 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 378 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 364 scoped_ptr<disk_cache::Entry*> entryptr, | 379 scoped_ptr<disk_cache::Entry*> entryptr, |
| 365 int rv) { | 380 int rv) { |
| 366 if (rv != net::OK) { | 381 if (rv != net::OK) { |
| 367 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, | 382 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, |
| 368 scoped_ptr<ServiceWorkerResponse>(), | 383 scoped_ptr<ServiceWorkerResponse>(), |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 720 |
| 706 ServiceWorkerCache::~ServiceWorkerCache() { | 721 ServiceWorkerCache::~ServiceWorkerCache() { |
| 707 } | 722 } |
| 708 | 723 |
| 709 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { | 724 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { |
| 710 return weak_ptr_factory_.GetWeakPtr(); | 725 return weak_ptr_factory_.GetWeakPtr(); |
| 711 } | 726 } |
| 712 | 727 |
| 713 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, | 728 void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request, |
| 714 scoped_ptr<ServiceWorkerResponse> response, | 729 scoped_ptr<ServiceWorkerResponse> response, |
| 715 const ErrorCallback& callback) { | 730 const ResponseCallback& callback) { |
| 716 scoped_ptr<storage::BlobDataHandle> blob_data_handle; | 731 scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
| 732 |
| 717 if (!response->blob_uuid.empty()) { | 733 if (!response->blob_uuid.empty()) { |
| 718 if (!blob_storage_context_) { | 734 if (!blob_storage_context_) { |
| 719 callback.Run(ErrorTypeStorage); | 735 callback.Run(ErrorTypeStorage, |
| 736 scoped_ptr<ServiceWorkerResponse>(), |
| 737 scoped_ptr<storage::BlobDataHandle>()); |
| 720 return; | 738 return; |
| 721 } | 739 } |
| 722 blob_data_handle = | 740 blob_data_handle = |
| 723 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); | 741 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
| 724 if (!blob_data_handle) { | 742 if (!blob_data_handle) { |
| 725 callback.Run(ErrorTypeStorage); | 743 callback.Run(ErrorTypeStorage, |
| 744 scoped_ptr<ServiceWorkerResponse>(), |
| 745 scoped_ptr<storage::BlobDataHandle>()); |
| 726 return; | 746 return; |
| 727 } | 747 } |
| 728 } | 748 } |
| 729 | 749 |
| 730 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl, | 750 base::Closure continuation = base::Bind(&ServiceWorkerCache::PutImpl, |
| 731 weak_ptr_factory_.GetWeakPtr(), | 751 weak_ptr_factory_.GetWeakPtr(), |
| 732 base::Passed(request.Pass()), | 752 base::Passed(request.Pass()), |
| 733 base::Passed(response.Pass()), | 753 base::Passed(response.Pass()), |
| 734 base::Passed(blob_data_handle.Pass()), | 754 base::Passed(blob_data_handle.Pass()), |
| 735 callback); | 755 callback); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 request_context_(request_context), | 878 request_context_(request_context), |
| 859 blob_storage_context_(blob_context), | 879 blob_storage_context_(blob_context), |
| 860 initialized_(false), | 880 initialized_(false), |
| 861 weak_ptr_factory_(this) { | 881 weak_ptr_factory_(this) { |
| 862 } | 882 } |
| 863 | 883 |
| 864 void ServiceWorkerCache::PutImpl( | 884 void ServiceWorkerCache::PutImpl( |
| 865 scoped_ptr<ServiceWorkerFetchRequest> request, | 885 scoped_ptr<ServiceWorkerFetchRequest> request, |
| 866 scoped_ptr<ServiceWorkerResponse> response, | 886 scoped_ptr<ServiceWorkerResponse> response, |
| 867 scoped_ptr<storage::BlobDataHandle> blob_data_handle, | 887 scoped_ptr<storage::BlobDataHandle> blob_data_handle, |
| 868 const ErrorCallback& callback) { | 888 const ResponseCallback& callback) { |
| 869 if (!backend_) { | 889 if (!backend_) { |
| 870 callback.Run(ErrorTypeStorage); | 890 callback.Run(ErrorTypeStorage, |
| 891 scoped_ptr<ServiceWorkerResponse>(), |
| 892 scoped_ptr<storage::BlobDataHandle>()); |
| 871 return; | 893 return; |
| 872 } | 894 } |
| 873 | 895 |
| 874 scoped_ptr<PutContext> put_context(new PutContext(request.Pass(), | 896 scoped_ptr<PutContext> put_context(new PutContext(request.Pass(), |
| 875 response.Pass(), | 897 response.Pass(), |
| 876 blob_data_handle.Pass(), | 898 blob_data_handle.Pass(), |
| 877 callback, | 899 callback, |
| 878 request_context_)); | 900 request_context_)); |
| 879 | 901 |
| 902 if (put_context->blob_data_handle) { |
| 903 // Grab another handle to the blob for the callback response. |
| 904 put_context->out_blob_data_handle = |
| 905 blob_storage_context_->GetBlobDataFromUUID( |
| 906 put_context->response->blob_uuid); |
| 907 } |
| 908 |
| 880 disk_cache::Entry** entry_ptr = &put_context->cache_entry; | 909 disk_cache::Entry** entry_ptr = &put_context->cache_entry; |
| 881 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); | 910 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); |
| 882 | 911 |
| 883 net::CompletionCallback create_entry_callback = | 912 net::CompletionCallback create_entry_callback = |
| 884 base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass())); | 913 base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass())); |
| 885 | 914 |
| 886 int rv = backend_->CreateEntry( | 915 int rv = backend_->CreateEntry( |
| 887 request_ptr->url.spec(), entry_ptr, create_entry_callback); | 916 request_ptr->url.spec(), entry_ptr, create_entry_callback); |
| 888 | 917 |
| 889 if (rv != net::ERR_IO_PENDING) | 918 if (rv != net::ERR_IO_PENDING) |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 initialized_ = true; | 1056 initialized_ = true; |
| 1028 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 1057 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| 1029 it != init_callbacks_.end(); | 1058 it != init_callbacks_.end(); |
| 1030 ++it) { | 1059 ++it) { |
| 1031 it->Run(); | 1060 it->Run(); |
| 1032 } | 1061 } |
| 1033 init_callbacks_.clear(); | 1062 init_callbacks_.clear(); |
| 1034 } | 1063 } |
| 1035 | 1064 |
| 1036 } // namespace content | 1065 } // namespace content |
| OLD | NEW |