Chromium Code Reviews| 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" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "content/browser/service_worker/service_worker_cache.pb.h" | 12 #include "content/browser/service_worker/service_worker_cache.pb.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "net/disk_cache/disk_cache.h" | 16 #include "net/disk_cache/disk_cache.h" |
| 17 #include "net/url_request/url_request_context.h" | 17 #include "net/url_request/url_request_context.h" |
| 18 #include "webkit/browser/blob/blob_data_handle.h" | 18 #include "webkit/browser/blob/blob_data_handle.h" |
| 19 #include "webkit/browser/blob/blob_storage_context.h" | 19 #include "webkit/browser/blob/blob_storage_context.h" |
| 20 #include "webkit/browser/blob/blob_url_request_job_factory.h" | 20 #include "webkit/browser/blob/blob_url_request_job_factory.h" |
| 21 | 21 |
| 22 namespace content { | 22 namespace content { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 struct EntriesDeleter; | |
| 25 | 26 |
| 26 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; | 27 typedef scoped_ptr<disk_cache::Backend> ScopedBackendPtr; |
| 27 typedef base::Callback<void(bool)> BoolCallback; | 28 typedef base::Callback<void(bool)> BoolCallback; |
| 28 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> | 29 typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> |
| 29 EntryBoolCallback; | 30 EntryBoolCallback; |
| 31 typedef base::Callback<void(scoped_ptr<ServiceWorkerRequestResponseHeaders>)> | |
| 32 HeadersCallback; | |
| 33 typedef std::vector<disk_cache::Entry*> Entries; | |
| 34 | |
| 35 // Automatically closes all of the entries in the vector when it goes out of | |
| 36 // scope. | |
| 37 typedef scoped_ptr<Entries, EntriesDeleter> ScopedEntriesPtr; | |
| 38 | |
| 30 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; | 39 enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
| 31 | 40 |
| 32 // The maximum size of an individual cache. Ultimately cache size is controlled | 41 // The maximum size of an individual cache. Ultimately cache size is controlled |
| 33 // per-origin. | 42 // per-origin. |
| 34 const int kMaxCacheBytes = 512 * 1024 * 1024; | 43 const int kMaxCacheBytes = 512 * 1024 * 1024; |
| 35 | 44 |
| 36 // Buffer size for cache and blob reading/writing. | 45 // Buffer size for cache and blob reading/writing. |
| 37 const int kBufferSize = 1024 * 512; | 46 const int kBufferSize = 1024 * 512; |
| 38 | 47 |
| 48 struct EntriesDeleter { | |
| 49 void operator()(Entries* entries) { | |
| 50 for (size_t i = 0, max = entries->size(); i < max; ++i) | |
| 51 entries->at(i)->Close(); | |
|
michaeln
2014/08/27 23:45:20
delete entries too?
jkarlin
2014/08/28 15:16:11
Done.
| |
| 52 } | |
| 53 }; | |
| 54 | |
| 39 struct ResponseReadContext { | 55 struct ResponseReadContext { |
| 40 ResponseReadContext(scoped_refptr<net::IOBufferWithSize> buff, | 56 ResponseReadContext(scoped_refptr<net::IOBufferWithSize> buff, |
| 41 scoped_refptr<storage::BlobData> blob) | 57 scoped_refptr<storage::BlobData> blob) |
| 42 : buffer(buff), blob_data(blob), total_bytes_read(0) {} | 58 : buffer(buff), blob_data(blob), total_bytes_read(0) {} |
| 43 | 59 |
| 44 scoped_refptr<net::IOBufferWithSize> buffer; | 60 scoped_refptr<net::IOBufferWithSize> buffer; |
| 45 scoped_refptr<storage::BlobData> blob_data; | 61 scoped_refptr<storage::BlobData> blob_data; |
| 46 int total_bytes_read; | 62 int total_bytes_read; |
| 47 | 63 |
| 48 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext); | 64 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, | 198 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, |
| 183 const ServiceWorkerCache::ResponseCallback& callback, | 199 const ServiceWorkerCache::ResponseCallback& callback, |
| 184 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 200 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 185 scoped_ptr<disk_cache::Entry*> entryptr, | 201 scoped_ptr<disk_cache::Entry*> entryptr, |
| 186 int rv); | 202 int rv); |
| 187 void MatchDidReadHeaderData( | 203 void MatchDidReadHeaderData( |
| 188 ServiceWorkerFetchRequest* request, | 204 ServiceWorkerFetchRequest* request, |
| 189 const ServiceWorkerCache::ResponseCallback& callback, | 205 const ServiceWorkerCache::ResponseCallback& callback, |
| 190 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 206 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 191 disk_cache::ScopedEntryPtr entry, | 207 disk_cache::ScopedEntryPtr entry, |
| 192 const scoped_refptr<net::IOBufferWithSize>& buffer, | 208 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers); |
| 193 int rv); | |
| 194 void MatchDidReadResponseBodyData( | 209 void MatchDidReadResponseBodyData( |
| 195 ServiceWorkerFetchRequest* request, | 210 ServiceWorkerFetchRequest* request, |
| 196 const ServiceWorkerCache::ResponseCallback& callback, | 211 const ServiceWorkerCache::ResponseCallback& callback, |
| 197 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 212 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 198 disk_cache::ScopedEntryPtr entry, | 213 disk_cache::ScopedEntryPtr entry, |
| 199 scoped_ptr<ServiceWorkerResponse> response, | 214 scoped_ptr<ServiceWorkerResponse> response, |
| 200 scoped_ptr<ResponseReadContext> response_context, | 215 scoped_ptr<ResponseReadContext> response_context, |
| 201 int rv); | 216 int rv); |
| 202 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, | 217 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, |
| 203 const ServiceWorkerCache::ResponseCallback& callback, | 218 const ServiceWorkerCache::ResponseCallback& callback, |
| 204 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 219 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 205 scoped_ptr<ServiceWorkerResponse> response, | 220 scoped_ptr<ServiceWorkerResponse> response, |
| 206 scoped_ptr<ResponseReadContext> response_context); | 221 scoped_ptr<ResponseReadContext> response_context); |
| 207 | 222 |
| 208 // Delete callbacks | 223 // Delete callbacks |
| 209 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, | 224 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, |
| 210 const ServiceWorkerCache::ErrorCallback& callback, | 225 const ServiceWorkerCache::ErrorCallback& callback, |
| 211 scoped_ptr<disk_cache::Entry*> entryptr, | 226 scoped_ptr<disk_cache::Entry*> entryptr, |
| 212 int rv); | 227 int rv); |
| 213 | 228 |
| 229 // Keys callback | |
| 230 void KeysDidOpenNextEntry(const ServiceWorkerCache::RequestsCallback& callback, | |
| 231 base::WeakPtr<ServiceWorkerCache> cache, | |
| 232 scoped_ptr<void*> iter, | |
| 233 scoped_ptr<disk_cache::Entry*> entryptr, | |
| 234 ScopedEntriesPtr entries, | |
| 235 int rv); | |
| 236 void KeysProcessNextEntry(const ServiceWorkerCache::RequestsCallback& callback, | |
| 237 scoped_ptr<ServiceWorkerCache::Requests> requests, | |
| 238 ScopedEntriesPtr entries, | |
| 239 const Entries::iterator& iter); | |
| 240 void KeysDidReadHeaders( | |
| 241 const ServiceWorkerCache::RequestsCallback& callback, | |
| 242 scoped_ptr<ServiceWorkerCache::Requests> out_requests, | |
| 243 ScopedEntriesPtr entries, | |
| 244 const Entries::iterator& iter, | |
| 245 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers); | |
| 246 | |
| 247 // Copy headers out of a cache entry and into a protobuf. The callback is | |
| 248 // guaranteed to be run. | |
| 249 void ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback); | |
| 250 void ReadHeadersDidReadHeaderData( | |
| 251 disk_cache::Entry* entry, | |
| 252 const HeadersCallback& callback, | |
| 253 const scoped_refptr<net::IOBufferWithSize>& buffer, | |
| 254 int rv); | |
| 255 | |
| 214 // CreateBackend callbacks | 256 // CreateBackend callbacks |
| 215 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, | 257 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, |
| 216 scoped_ptr<ScopedBackendPtr> backend_ptr, | 258 scoped_ptr<ScopedBackendPtr> backend_ptr, |
| 217 base::WeakPtr<ServiceWorkerCache> cache, | 259 base::WeakPtr<ServiceWorkerCache> cache, |
| 218 int rv); | 260 int rv); |
| 219 | 261 |
| 220 void PutDidCreateEntry(ServiceWorkerFetchRequest* request, | 262 void PutDidCreateEntry(ServiceWorkerFetchRequest* request, |
| 221 ServiceWorkerResponse* response, | 263 ServiceWorkerResponse* response, |
| 222 const ServiceWorkerCache::ErrorCallback& callback, | 264 const ServiceWorkerCache::ErrorCallback& callback, |
| 223 scoped_ptr<disk_cache::Entry*> entryptr, | 265 scoped_ptr<disk_cache::Entry*> entryptr, |
| 224 scoped_ptr<storage::BlobDataHandle> blob_data_handle, | 266 scoped_ptr<storage::BlobDataHandle> blob_data_handle, |
| 225 net::URLRequestContext* request_context, | 267 net::URLRequestContext* request_context, |
| 226 int rv) { | 268 int rv) { |
| 227 if (rv != net::OK) { | 269 if (rv != net::OK) |
| 228 callback.Run(ServiceWorkerCache::ErrorTypeExists); | 270 return callback.Run(ServiceWorkerCache::ErrorTypeExists); |
| 229 return; | |
| 230 } | |
| 231 | 271 |
| 232 DCHECK(entryptr); | 272 DCHECK(entryptr); |
| 233 disk_cache::ScopedEntryPtr entry(*entryptr); | 273 disk_cache::ScopedEntryPtr entry(*entryptr); |
| 234 | 274 |
| 235 ServiceWorkerRequestResponseHeaders headers; | 275 ServiceWorkerRequestResponseHeaders headers; |
| 236 headers.set_method(request->method); | 276 headers.set_method(request->method); |
| 237 | 277 |
| 238 headers.set_status_code(response->status_code); | 278 headers.set_status_code(response->status_code); |
| 239 headers.set_status_text(response->status_text); | 279 headers.set_status_text(response->status_text); |
| 240 for (std::map<std::string, std::string>::const_iterator it = | 280 for (std::map<std::string, std::string>::const_iterator it = |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 251 response->headers.begin(); | 291 response->headers.begin(); |
| 252 it != response->headers.end(); | 292 it != response->headers.end(); |
| 253 ++it) { | 293 ++it) { |
| 254 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = | 294 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map = |
| 255 headers.add_response_headers(); | 295 headers.add_response_headers(); |
| 256 header_map->set_name(it->first); | 296 header_map->set_name(it->first); |
| 257 header_map->set_value(it->second); | 297 header_map->set_value(it->second); |
| 258 } | 298 } |
| 259 | 299 |
| 260 scoped_ptr<std::string> serialized(new std::string()); | 300 scoped_ptr<std::string> serialized(new std::string()); |
| 261 if (!headers.SerializeToString(serialized.get())) { | 301 if (!headers.SerializeToString(serialized.get())) |
| 262 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 302 return callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
| 263 return; | |
| 264 } | |
| 265 | 303 |
| 266 scoped_refptr<net::StringIOBuffer> buffer( | 304 scoped_refptr<net::StringIOBuffer> buffer( |
| 267 new net::StringIOBuffer(serialized.Pass())); | 305 new net::StringIOBuffer(serialized.Pass())); |
| 268 | 306 |
| 269 // Get a temporary copy of the entry pointer before passing it in base::Bind. | 307 // Get a temporary copy of the entry pointer before passing it in base::Bind. |
| 270 disk_cache::Entry* tmp_entry_ptr = entry.get(); | 308 disk_cache::Entry* tmp_entry_ptr = entry.get(); |
| 271 | 309 |
| 272 net::CompletionCallback write_headers_callback = | 310 net::CompletionCallback write_headers_callback = |
| 273 base::Bind(PutDidWriteHeaders, | 311 base::Bind(PutDidWriteHeaders, |
| 274 response, | 312 response, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 291 | 329 |
| 292 void PutDidWriteHeaders(ServiceWorkerResponse* response, | 330 void PutDidWriteHeaders(ServiceWorkerResponse* response, |
| 293 const ServiceWorkerCache::ErrorCallback& callback, | 331 const ServiceWorkerCache::ErrorCallback& callback, |
| 294 disk_cache::ScopedEntryPtr entry, | 332 disk_cache::ScopedEntryPtr entry, |
| 295 scoped_ptr<storage::BlobDataHandle> blob_data_handle, | 333 scoped_ptr<storage::BlobDataHandle> blob_data_handle, |
| 296 net::URLRequestContext* request_context, | 334 net::URLRequestContext* request_context, |
| 297 int expected_bytes, | 335 int expected_bytes, |
| 298 int rv) { | 336 int rv) { |
| 299 if (rv != expected_bytes) { | 337 if (rv != expected_bytes) { |
| 300 entry->Doom(); | 338 entry->Doom(); |
| 301 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 339 return callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
| 302 return; | |
| 303 } | 340 } |
| 304 | 341 |
| 305 // The metadata is written, now for the response content. The data is streamed | 342 // The metadata is written, now for the response content. The data is streamed |
| 306 // from the blob into the cache entry. | 343 // from the blob into the cache entry. |
| 307 | 344 |
| 308 if (response->blob_uuid.empty()) { | 345 if (response->blob_uuid.empty()) |
| 309 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 346 return callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 310 return; | |
| 311 } | |
| 312 | 347 |
| 313 DCHECK(blob_data_handle); | 348 DCHECK(blob_data_handle); |
| 314 | 349 |
| 315 scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass())); | 350 scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass())); |
| 316 BlobReader* reader_ptr = reader.get(); | 351 BlobReader* reader_ptr = reader.get(); |
| 317 | 352 |
| 318 reader_ptr->StreamBlobToCache( | 353 reader_ptr->StreamBlobToCache( |
| 319 request_context, | 354 request_context, |
| 320 blob_data_handle.Pass(), | 355 blob_data_handle.Pass(), |
| 321 base::Bind( | 356 base::Bind( |
| 322 PutDidWriteBlobToCache, callback, base::Passed(reader.Pass()))); | 357 PutDidWriteBlobToCache, callback, base::Passed(reader.Pass()))); |
| 323 } | 358 } |
| 324 | 359 |
| 325 void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback, | 360 void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback, |
| 326 scoped_ptr<BlobReader> blob_reader, | 361 scoped_ptr<BlobReader> blob_reader, |
| 327 disk_cache::ScopedEntryPtr entry, | 362 disk_cache::ScopedEntryPtr entry, |
| 328 bool success) { | 363 bool success) { |
| 329 if (!success) { | 364 if (!success) { |
| 330 entry->Doom(); | 365 entry->Doom(); |
| 331 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 366 return callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
| 332 return; | |
| 333 } | 367 } |
| 334 | 368 |
| 335 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 369 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 336 } | 370 } |
| 337 | 371 |
| 338 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, | 372 void MatchDidOpenEntry(ServiceWorkerFetchRequest* request, |
| 339 const ServiceWorkerCache::ResponseCallback& callback, | 373 const ServiceWorkerCache::ResponseCallback& callback, |
| 340 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 374 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 341 scoped_ptr<disk_cache::Entry*> entryptr, | 375 scoped_ptr<disk_cache::Entry*> entryptr, |
| 342 int rv) { | 376 int rv) { |
| 343 if (rv != net::OK) { | 377 if (rv != net::OK) { |
| 344 callback.Run(ServiceWorkerCache::ErrorTypeNotFound, | 378 return callback.Run(ServiceWorkerCache::ErrorTypeNotFound, |
| 345 scoped_ptr<ServiceWorkerResponse>(), | 379 scoped_ptr<ServiceWorkerResponse>(), |
| 346 scoped_ptr<storage::BlobDataHandle>()); | 380 scoped_ptr<storage::BlobDataHandle>()); |
| 347 return; | |
| 348 } | 381 } |
| 349 | 382 |
| 350 DCHECK(entryptr); | 383 DCHECK(entryptr); |
| 351 disk_cache::ScopedEntryPtr entry(*entryptr); | 384 disk_cache::ScopedEntryPtr entry(*entryptr); |
| 352 | 385 |
| 353 scoped_refptr<net::IOBufferWithSize> buffer( | |
| 354 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); | |
| 355 | |
| 356 // Copy the entry pointer before passing it in base::Bind. | 386 // Copy the entry pointer before passing it in base::Bind. |
| 357 disk_cache::Entry* tmp_entry_ptr = entry.get(); | 387 disk_cache::Entry* tmp_entry_ptr = entry.get(); |
| 358 | 388 |
| 359 net::CompletionCallback read_header_callback = | 389 HeadersCallback headers_callback = base::Bind(MatchDidReadHeaderData, |
| 360 base::Bind(MatchDidReadHeaderData, | 390 request, |
| 361 request, | 391 callback, |
| 362 callback, | 392 blob_storage, |
| 363 blob_storage, | 393 base::Passed(entry.Pass())); |
| 364 base::Passed(entry.Pass()), | |
| 365 buffer); | |
| 366 | 394 |
| 367 int read_rv = tmp_entry_ptr->ReadData( | 395 ReadHeaders(tmp_entry_ptr, headers_callback); |
| 368 INDEX_HEADERS, 0, buffer.get(), buffer->size(), read_header_callback); | |
| 369 | |
| 370 if (read_rv != net::ERR_IO_PENDING) | |
| 371 read_header_callback.Run(read_rv); | |
| 372 } | 396 } |
| 373 | 397 |
| 374 void MatchDidReadHeaderData( | 398 void MatchDidReadHeaderData( |
| 375 ServiceWorkerFetchRequest* request, | 399 ServiceWorkerFetchRequest* request, |
| 376 const ServiceWorkerCache::ResponseCallback& callback, | 400 const ServiceWorkerCache::ResponseCallback& callback, |
| 377 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 401 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 378 disk_cache::ScopedEntryPtr entry, | 402 disk_cache::ScopedEntryPtr entry, |
| 379 const scoped_refptr<net::IOBufferWithSize>& buffer, | 403 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { |
| 380 int rv) { | 404 if (!headers) { |
| 381 if (rv != buffer->size()) { | 405 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 382 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 406 scoped_ptr<ServiceWorkerResponse>(), |
| 383 scoped_ptr<ServiceWorkerResponse>(), | 407 scoped_ptr<storage::BlobDataHandle>()); |
| 384 scoped_ptr<storage::BlobDataHandle>()); | |
| 385 | |
| 386 return; | |
| 387 } | |
| 388 | |
| 389 ServiceWorkerRequestResponseHeaders headers; | |
| 390 | |
| 391 if (!headers.ParseFromArray(buffer->data(), buffer->size())) { | |
| 392 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | |
| 393 scoped_ptr<ServiceWorkerResponse>(), | |
| 394 scoped_ptr<storage::BlobDataHandle>()); | |
| 395 | |
| 396 return; | |
| 397 } | 408 } |
| 398 | 409 |
| 399 scoped_ptr<ServiceWorkerResponse> response( | 410 scoped_ptr<ServiceWorkerResponse> response( |
| 400 new ServiceWorkerResponse(request->url, | 411 new ServiceWorkerResponse(request->url, |
| 401 headers.status_code(), | 412 headers->status_code(), |
| 402 headers.status_text(), | 413 headers->status_text(), |
| 403 std::map<std::string, std::string>(), | 414 std::map<std::string, std::string>(), |
| 404 "")); | 415 "")); |
| 405 | 416 |
| 406 for (int i = 0; i < headers.response_headers_size(); ++i) { | 417 for (int i = 0; i < headers->response_headers_size(); ++i) { |
| 407 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | 418 const ServiceWorkerRequestResponseHeaders::HeaderMap header = |
| 408 headers.response_headers(i); | 419 headers->response_headers(i); |
| 409 response->headers.insert(std::make_pair(header.name(), header.value())); | 420 response->headers.insert(std::make_pair(header.name(), header.value())); |
| 410 } | 421 } |
| 411 | 422 |
| 412 // TODO(jkarlin): Insert vary validation here. | 423 // TODO(jkarlin): Insert vary validation here. |
| 413 | 424 |
| 414 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { | 425 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
| 415 callback.Run(ServiceWorkerCache::ErrorTypeOK, | 426 return callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 416 response.Pass(), | 427 response.Pass(), |
| 417 scoped_ptr<storage::BlobDataHandle>()); | 428 scoped_ptr<storage::BlobDataHandle>()); |
| 418 return; | |
| 419 } | 429 } |
| 420 | 430 |
| 421 // Stream the response body into a blob. | 431 // Stream the response body into a blob. |
| 422 if (!blob_storage) { | 432 if (!blob_storage) { |
| 423 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 433 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 424 scoped_ptr<ServiceWorkerResponse>(), | 434 scoped_ptr<ServiceWorkerResponse>(), |
| 425 scoped_ptr<storage::BlobDataHandle>()); | 435 scoped_ptr<storage::BlobDataHandle>()); |
| 426 | |
| 427 return; | |
| 428 } | 436 } |
| 429 | 437 |
| 430 response->blob_uuid = base::GenerateGUID(); | 438 response->blob_uuid = base::GenerateGUID(); |
| 431 | 439 |
| 432 scoped_refptr<storage::BlobData> blob_data = | 440 scoped_refptr<storage::BlobData> blob_data = |
| 433 new storage::BlobData(response->blob_uuid); | 441 new storage::BlobData(response->blob_uuid); |
| 434 scoped_refptr<net::IOBufferWithSize> response_body_buffer( | 442 scoped_refptr<net::IOBufferWithSize> response_body_buffer( |
| 435 new net::IOBufferWithSize(kBufferSize)); | 443 new net::IOBufferWithSize(kBufferSize)); |
| 436 | 444 |
| 437 scoped_ptr<ResponseReadContext> read_context( | 445 scoped_ptr<ResponseReadContext> read_context( |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 461 | 469 |
| 462 void MatchDidReadResponseBodyData( | 470 void MatchDidReadResponseBodyData( |
| 463 ServiceWorkerFetchRequest* request, | 471 ServiceWorkerFetchRequest* request, |
| 464 const ServiceWorkerCache::ResponseCallback& callback, | 472 const ServiceWorkerCache::ResponseCallback& callback, |
| 465 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 473 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 466 disk_cache::ScopedEntryPtr entry, | 474 disk_cache::ScopedEntryPtr entry, |
| 467 scoped_ptr<ServiceWorkerResponse> response, | 475 scoped_ptr<ServiceWorkerResponse> response, |
| 468 scoped_ptr<ResponseReadContext> response_context, | 476 scoped_ptr<ResponseReadContext> response_context, |
| 469 int rv) { | 477 int rv) { |
| 470 if (rv < 0) { | 478 if (rv < 0) { |
| 471 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 479 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 472 scoped_ptr<ServiceWorkerResponse>(), | 480 scoped_ptr<ServiceWorkerResponse>(), |
| 473 scoped_ptr<storage::BlobDataHandle>()); | 481 scoped_ptr<storage::BlobDataHandle>()); |
| 474 return; | |
| 475 } | 482 } |
| 476 | 483 |
| 477 if (rv == 0) { | 484 if (rv == 0) { |
| 478 MatchDoneWithBody(request, | 485 MatchDoneWithBody(request, |
| 479 callback, | 486 callback, |
| 480 blob_storage, | 487 blob_storage, |
| 481 response.Pass(), | 488 response.Pass(), |
| 482 response_context.Pass()); | 489 response_context.Pass()); |
| 483 return; | 490 return; |
| 484 } | 491 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 512 if (read_rv != net::ERR_IO_PENDING) | 519 if (read_rv != net::ERR_IO_PENDING) |
| 513 read_callback.Run(read_rv); | 520 read_callback.Run(read_rv); |
| 514 } | 521 } |
| 515 | 522 |
| 516 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, | 523 void MatchDoneWithBody(ServiceWorkerFetchRequest* request, |
| 517 const ServiceWorkerCache::ResponseCallback& callback, | 524 const ServiceWorkerCache::ResponseCallback& callback, |
| 518 base::WeakPtr<storage::BlobStorageContext> blob_storage, | 525 base::WeakPtr<storage::BlobStorageContext> blob_storage, |
| 519 scoped_ptr<ServiceWorkerResponse> response, | 526 scoped_ptr<ServiceWorkerResponse> response, |
| 520 scoped_ptr<ResponseReadContext> response_context) { | 527 scoped_ptr<ResponseReadContext> response_context) { |
| 521 if (!blob_storage) { | 528 if (!blob_storage) { |
| 522 callback.Run(ServiceWorkerCache::ErrorTypeStorage, | 529 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, |
| 523 scoped_ptr<ServiceWorkerResponse>(), | 530 scoped_ptr<ServiceWorkerResponse>(), |
| 524 scoped_ptr<storage::BlobDataHandle>()); | 531 scoped_ptr<storage::BlobDataHandle>()); |
| 525 return; | |
| 526 } | 532 } |
| 527 | 533 |
| 528 scoped_ptr<storage::BlobDataHandle> blob_data_handle( | 534 scoped_ptr<storage::BlobDataHandle> blob_data_handle( |
| 529 blob_storage->AddFinishedBlob(response_context->blob_data.get())); | 535 blob_storage->AddFinishedBlob(response_context->blob_data.get())); |
| 530 | 536 |
| 531 callback.Run(ServiceWorkerCache::ErrorTypeOK, | 537 callback.Run(ServiceWorkerCache::ErrorTypeOK, |
| 532 response.Pass(), | 538 response.Pass(), |
| 533 blob_data_handle.Pass()); | 539 blob_data_handle.Pass()); |
| 534 } | 540 } |
| 535 | 541 |
| 536 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, | 542 void DeleteDidOpenEntry(ServiceWorkerFetchRequest* request, |
| 537 const ServiceWorkerCache::ErrorCallback& callback, | 543 const ServiceWorkerCache::ErrorCallback& callback, |
| 538 scoped_ptr<disk_cache::Entry*> entryptr, | 544 scoped_ptr<disk_cache::Entry*> entryptr, |
| 539 int rv) { | 545 int rv) { |
| 540 if (rv != net::OK) { | 546 if (rv != net::OK) |
| 541 callback.Run(ServiceWorkerCache::ErrorTypeNotFound); | 547 return callback.Run(ServiceWorkerCache::ErrorTypeNotFound); |
| 542 return; | |
| 543 } | |
| 544 | 548 |
| 545 DCHECK(entryptr); | 549 DCHECK(entryptr); |
| 546 disk_cache::ScopedEntryPtr entry(*entryptr); | 550 disk_cache::ScopedEntryPtr entry(*entryptr); |
| 547 | 551 |
| 548 entry->Doom(); | 552 entry->Doom(); |
| 549 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 553 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 550 } | 554 } |
| 551 | 555 |
| 556 void KeysDidOpenNextEntry(const ServiceWorkerCache::RequestsCallback& callback, | |
| 557 base::WeakPtr<ServiceWorkerCache> cache, | |
| 558 scoped_ptr<void*> iter, | |
|
michaeln
2014/08/27 23:45:20
might be nice to distinguish the void* iter from t
jkarlin
2014/08/28 15:16:11
Done.
| |
| 559 scoped_ptr<disk_cache::Entry*> entryptr, | |
| 560 ScopedEntriesPtr entries, | |
| 561 int rv) { | |
| 562 if (rv == net::ERR_FAILED) { | |
| 563 // Enumeration is complete, extract the requests from the entries. | |
| 564 Entries::iterator iter = entries->begin(); | |
| 565 scoped_ptr<ServiceWorkerCache::Requests> out_requests( | |
| 566 new ServiceWorkerCache::Requests()); | |
|
michaeln
2014/08/27 23:45:20
ah ha, here's where the collection to hold the res
jkarlin
2014/08/28 15:16:10
Done.
| |
| 567 return KeysProcessNextEntry( | |
|
michaeln
2014/08/27 23:45:20
its odd to see return <something> in a function wi
jkarlin
2014/08/28 15:16:10
Done for the whole file.
| |
| 568 callback, out_requests.Pass(), entries.Pass(), iter); | |
| 569 } | |
| 570 | |
| 571 if (rv < 0 || !cache) { | |
| 572 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, | |
| 573 scoped_ptr<ServiceWorkerCache::Requests>()); | |
| 574 } | |
| 575 | |
| 576 entries->push_back(*entryptr); | |
| 577 | |
| 578 void** iter_ptr = iter.get(); | |
| 579 disk_cache::Entry** entry_ptr = entryptr.get(); | |
| 580 | |
| 581 net::CompletionCallback open_entry_callback = | |
| 582 base::Bind(KeysDidOpenNextEntry, | |
| 583 callback, | |
| 584 cache, | |
| 585 base::Passed(iter.Pass()), | |
| 586 base::Passed(entryptr.Pass()), | |
| 587 base::Passed(entries.Pass())); | |
| 588 | |
| 589 // Enumerate the next entry. | |
| 590 int rvv = | |
|
michaeln
2014/08/27 23:45:20
looks like you could just use the existing paramet
jkarlin
2014/08/28 15:16:11
Done.
| |
| 591 cache->backend()->OpenNextEntry(iter_ptr, entry_ptr, open_entry_callback); | |
|
michaeln
2014/08/27 23:45:20
i was wondering what caused backend() to be added
jkarlin
2014/08/28 15:16:10
You're right, better to hide backend. I'm not gai
| |
| 592 | |
| 593 if (rvv != net::ERR_IO_PENDING) | |
| 594 open_entry_callback.Run(rvv); | |
| 595 } | |
| 596 | |
| 597 void KeysProcessNextEntry(const ServiceWorkerCache::RequestsCallback& callback, | |
| 598 scoped_ptr<ServiceWorkerCache::Requests> requests, | |
| 599 ScopedEntriesPtr entries, | |
| 600 const Entries::iterator& iter) { | |
| 601 if (iter == entries->end()) | |
| 602 return callback.Run(ServiceWorkerCache::ErrorTypeOK, requests.Pass()); | |
|
michaeln
2014/08/27 23:45:20
This is the end of the line in the expected case,
jkarlin
2014/08/28 15:16:11
Done.
| |
| 603 | |
| 604 ReadHeaders(*iter, | |
| 605 base::Bind(KeysDidReadHeaders, | |
| 606 callback, | |
| 607 base::Passed(requests.Pass()), | |
| 608 base::Passed(entries.Pass()), | |
| 609 iter)); | |
| 610 } | |
| 611 | |
| 612 void KeysDidReadHeaders( | |
| 613 const ServiceWorkerCache::RequestsCallback& callback, | |
| 614 scoped_ptr<ServiceWorkerCache::Requests> out_requests, | |
| 615 ScopedEntriesPtr entries, | |
| 616 const Entries::iterator& iter, | |
| 617 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers) { | |
| 618 disk_cache::Entry* entry = *iter; | |
| 619 | |
| 620 if (!headers) { | |
| 621 entry->Doom(); | |
|
michaeln
2014/08/27 23:45:20
Interesting, a subsequent call to Keys() will yeil
jkarlin
2014/08/28 15:16:10
Done.
| |
| 622 return callback.Run(ServiceWorkerCache::ErrorTypeStorage, | |
| 623 out_requests.Pass()); | |
| 624 } | |
| 625 | |
| 626 out_requests->push_back( | |
| 627 ServiceWorkerFetchRequest(GURL(entry->GetKey()), | |
| 628 headers->method(), | |
| 629 std::map<std::string, std::string>(), | |
| 630 GURL(), | |
| 631 false)); | |
| 632 | |
| 633 std::map<std::string, std::string>& req_headers = | |
| 634 out_requests->back().headers; | |
| 635 | |
| 636 for (int i = 0; i < headers->request_headers_size(); ++i) { | |
| 637 const ServiceWorkerRequestResponseHeaders::HeaderMap header = | |
| 638 headers->request_headers(i); | |
| 639 req_headers.insert(std::make_pair(header.name(), header.value())); | |
| 640 } | |
| 641 | |
| 642 KeysProcessNextEntry(callback, out_requests.Pass(), entries.Pass(), iter + 1); | |
| 643 } | |
| 644 | |
| 645 void ReadHeaders(disk_cache::Entry* entry, const HeadersCallback& callback) { | |
| 646 DCHECK(entry); | |
| 647 | |
| 648 scoped_refptr<net::IOBufferWithSize> buffer( | |
| 649 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); | |
| 650 | |
| 651 net::CompletionCallback read_header_callback = | |
| 652 base::Bind(ReadHeadersDidReadHeaderData, entry, callback, buffer); | |
| 653 | |
| 654 int read_rv = entry->ReadData( | |
| 655 INDEX_HEADERS, 0, buffer.get(), buffer->size(), read_header_callback); | |
| 656 | |
| 657 if (read_rv != net::ERR_IO_PENDING) | |
| 658 read_header_callback.Run(read_rv); | |
| 659 } | |
| 660 | |
| 661 void ReadHeadersDidReadHeaderData( | |
| 662 disk_cache::Entry* entry, | |
| 663 const HeadersCallback& callback, | |
| 664 const scoped_refptr<net::IOBufferWithSize>& buffer, | |
| 665 int rv) { | |
| 666 if (rv != buffer->size()) | |
| 667 return callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); | |
| 668 | |
| 669 scoped_ptr<ServiceWorkerRequestResponseHeaders> headers( | |
| 670 new ServiceWorkerRequestResponseHeaders()); | |
| 671 | |
| 672 if (!headers->ParseFromArray(buffer->data(), buffer->size())) | |
| 673 return callback.Run(scoped_ptr<ServiceWorkerRequestResponseHeaders>()); | |
| 674 | |
| 675 callback.Run(headers.Pass()); | |
| 676 } | |
| 677 | |
| 552 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, | 678 void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback, |
| 553 scoped_ptr<ScopedBackendPtr> backend_ptr, | 679 scoped_ptr<ScopedBackendPtr> backend_ptr, |
| 554 base::WeakPtr<ServiceWorkerCache> cache, | 680 base::WeakPtr<ServiceWorkerCache> cache, |
| 555 int rv) { | 681 int rv) { |
| 556 if (rv != net::OK || !cache) { | 682 if (rv != net::OK || !cache) |
| 557 callback.Run(ServiceWorkerCache::ErrorTypeStorage); | 683 return callback.Run(ServiceWorkerCache::ErrorTypeStorage); |
| 558 return; | 684 |
| 559 } | |
| 560 cache->set_backend(backend_ptr->Pass()); | 685 cache->set_backend(backend_ptr->Pass()); |
| 561 callback.Run(ServiceWorkerCache::ErrorTypeOK); | 686 callback.Run(ServiceWorkerCache::ErrorTypeOK); |
| 562 } | 687 } |
| 563 | 688 |
| 564 } // namespace | 689 } // namespace |
| 565 | 690 |
| 566 // static | 691 // static |
| 567 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( | 692 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( |
| 568 net::URLRequestContext* request_context, | 693 net::URLRequestContext* request_context, |
| 569 base::WeakPtr<storage::BlobStorageContext> blob_context) { | 694 base::WeakPtr<storage::BlobStorageContext> blob_context) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 DCHECK(backend_); | 754 DCHECK(backend_); |
| 630 | 755 |
| 631 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); | 756 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); |
| 632 | 757 |
| 633 disk_cache::Entry** entry_ptr = entry.get(); | 758 disk_cache::Entry** entry_ptr = entry.get(); |
| 634 | 759 |
| 635 scoped_ptr<storage::BlobDataHandle> blob_data_handle; | 760 scoped_ptr<storage::BlobDataHandle> blob_data_handle; |
| 636 | 761 |
| 637 if (!response->blob_uuid.empty()) { | 762 if (!response->blob_uuid.empty()) { |
| 638 if (!blob_storage_context_) { | 763 if (!blob_storage_context_) { |
| 639 callback.Run(ErrorTypeStorage); | 764 return callback.Run(ErrorTypeStorage); |
|
michaeln
2014/08/27 23:45:20
why?
jkarlin
2014/08/28 15:16:10
Done.
| |
| 640 return; | |
| 641 } | 765 } |
| 642 blob_data_handle = | 766 blob_data_handle = |
| 643 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); | 767 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid); |
| 644 if (!blob_data_handle) { | 768 if (!blob_data_handle) { |
| 645 callback.Run(ErrorTypeStorage); | 769 return callback.Run(ErrorTypeStorage); |
| 646 return; | |
| 647 } | 770 } |
| 648 } | 771 } |
| 649 | 772 |
| 650 net::CompletionCallback create_entry_callback = | 773 net::CompletionCallback create_entry_callback = |
| 651 base::Bind(PutDidCreateEntry, | 774 base::Bind(PutDidCreateEntry, |
| 652 request, | 775 request, |
| 653 response, | 776 response, |
| 654 callback, | 777 callback, |
| 655 base::Passed(entry.Pass()), | 778 base::Passed(entry.Pass()), |
| 656 base::Passed(blob_data_handle.Pass()), | 779 base::Passed(blob_data_handle.Pass()), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 | 817 |
| 695 net::CompletionCallback open_entry_callback = base::Bind( | 818 net::CompletionCallback open_entry_callback = base::Bind( |
| 696 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); | 819 DeleteDidOpenEntry, request, callback, base::Passed(entry.Pass())); |
| 697 | 820 |
| 698 int rv = | 821 int rv = |
| 699 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); | 822 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback); |
| 700 if (rv != net::ERR_IO_PENDING) | 823 if (rv != net::ERR_IO_PENDING) |
| 701 open_entry_callback.Run(rv); | 824 open_entry_callback.Run(rv); |
| 702 } | 825 } |
| 703 | 826 |
| 827 void ServiceWorkerCache::Keys(const RequestsCallback& callback) { | |
| 828 DCHECK(backend_); | |
| 829 | |
| 830 scoped_ptr<void*> iter(new void*(NULL)); | |
| 831 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*); | |
| 832 | |
| 833 void** iter_ptr = iter.get(); | |
| 834 disk_cache::Entry** entry_ptr = entry.get(); | |
| 835 | |
| 836 // Load up all of the entries into a vector and then read the request data | |
|
michaeln
2014/08/27 23:45:20
It might help to expand on this comment to better
jkarlin
2014/08/28 15:16:10
Done.
| |
| 837 // from them. This has to be done in two steps because enumeration breaks if | |
| 838 // entries are altered (such as reading header data) while enumerating. | |
|
michaeln
2014/08/27 23:45:20
how does reading header data alter it?
jkarlin
2014/08/28 15:16:10
It changes the "last_used" field which seems buggy
| |
| 839 ScopedEntriesPtr entries(new Entries()); | |
| 840 | |
| 841 net::CompletionCallback open_entry_callback = | |
| 842 base::Bind(KeysDidOpenNextEntry, | |
| 843 callback, | |
| 844 weak_ptr_factory_.GetWeakPtr(), | |
| 845 base::Passed(iter.Pass()), | |
| 846 base::Passed(entry.Pass()), | |
| 847 base::Passed(entries.Pass())); | |
| 848 | |
| 849 int rv = backend_->OpenNextEntry(iter_ptr, entry_ptr, open_entry_callback); | |
| 850 | |
| 851 if (rv != net::ERR_IO_PENDING) | |
| 852 open_entry_callback.Run(rv); | |
| 853 } | |
| 854 | |
| 704 bool ServiceWorkerCache::HasCreatedBackend() const { | 855 bool ServiceWorkerCache::HasCreatedBackend() const { |
| 705 return backend_; | 856 return backend_; |
| 706 } | 857 } |
| 707 | 858 |
| 708 ServiceWorkerCache::ServiceWorkerCache( | 859 ServiceWorkerCache::ServiceWorkerCache( |
| 709 const base::FilePath& path, | 860 const base::FilePath& path, |
| 710 net::URLRequestContext* request_context, | 861 net::URLRequestContext* request_context, |
| 711 base::WeakPtr<storage::BlobStorageContext> blob_context) | 862 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 712 : path_(path), | 863 : path_(path), |
| 713 request_context_(request_context), | 864 request_context_(request_context), |
| 714 blob_storage_context_(blob_context), | 865 blob_storage_context_(blob_context), |
| 715 weak_ptr_factory_(this) { | 866 weak_ptr_factory_(this) { |
| 716 } | 867 } |
| 717 | 868 |
| 718 } // namespace content | 869 } // namespace content |
| OLD | NEW |