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 |