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 |