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

Side by Side Diff: content/browser/service_worker/service_worker_cache.cc

Issue 465463002: Initial implementation of ServiceWorkerCache. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cache2
Patch Set: Put and Match mostly work with blobs but the first few bytes are screwy Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/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"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "content/browser/fileapi/chrome_blob_storage_context.h"
13 #include "content/browser/service_worker/service_worker_cache.pb.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/disk_cache/disk_cache.h"
10 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context.h"
19 #include "webkit/browser/blob/blob_data_handle.h"
11 #include "webkit/browser/blob/blob_storage_context.h" 20 #include "webkit/browser/blob/blob_storage_context.h"
21 #include "webkit/browser/blob/blob_url_request_job_factory.h"
12 22
13 namespace content { 23 namespace content {
14 24
25 namespace {
26 // The maximum size of an individual cache.
27 const int kMaxCacheBytes = 5 * 1024 * 1024;
michaeln 2014/08/14 10:35:20 why so small?
jkarlin 2014/08/14 19:53:32 Great question. No idea what's proper. Upped to
28
29 // Buffer size for cache and blob reading/writing.
30 const int kBufferSize = 1024 * 512;
michaeln 2014/08/14 10:35:19 why so big :)
jkarlin 2014/08/14 19:53:33 This is the size that we read from the cache when
31 }
32
33 struct ServiceWorkerCache::ResponseReadContext {
34 explicit ResponseReadContext(scoped_refptr<net::IOBufferWithSize> buff,
michaeln 2014/08/14 10:35:20 is explicit needed with two args
jkarlin 2014/08/14 19:53:32 Done.
35 scoped_refptr<webkit_blob::BlobData> blob)
36 : buffer(buff), blob_data(blob), total_bytes_read(0) {}
37
38 scoped_refptr<net::IOBufferWithSize> buffer;
39 scoped_refptr<webkit_blob::BlobData> blob_data;
40 int total_bytes_read;
41
42 DISALLOW_COPY_AND_ASSIGN(ResponseReadContext);
43 };
44
45 // Streams data from a blob and writes it to a given disk_cache::Entry.
46 // This class is owned by the callback function passed to Start().
47 class ServiceWorkerCache::BlobReader : public net::URLRequest::Delegate {
michaeln 2014/08/14 10:35:20 this is very similar to what ServiceWorkerWriteToC
jkarlin 2014/08/14 19:53:33 True, but not a straight-forward adaptation.
48 public:
49 BlobReader(disk_cache::Entry* entry)
50 : cache_entry_offset_(0),
51 entry_(entry),
52 buffer_(new net::IOBufferWithSize(kBufferSize)) {
53 DCHECK(entry_);
54 }
55
56 void StreamBlobToCache(
57 net::URLRequestContext* request_context,
58 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle,
59 const BoolCallback& callback) {
60 callback_ = callback;
61 blob_request_ = webkit_blob::BlobProtocolHandler::CreateBlobRequest(
62 blob_data_handle.Pass(), request_context, this);
63 blob_request_->Start();
64 }
65
66 // net::URLRequest::Delegate overrides for reading blobs.
67 virtual void OnReceivedRedirect(net::URLRequest* request,
68 const GURL& new_url,
69 bool* defer_redirect) OVERRIDE {
70 NOTREACHED();
71 }
72 virtual void OnAuthRequired(net::URLRequest* request,
73 net::AuthChallengeInfo* auth_info) OVERRIDE {
74 NOTREACHED();
75 }
76 virtual void OnCertificateRequested(
77 net::URLRequest* request,
78 net::SSLCertRequestInfo* cert_request_info) OVERRIDE {
79 NOTREACHED();
80 }
81 virtual void OnSSLCertificateError(net::URLRequest* request,
82 const net::SSLInfo& ssl_info,
83 bool fatal) OVERRIDE {
84 NOTREACHED();
85 }
86 virtual void OnBeforeNetworkStart(net::URLRequest* request,
87 bool* defer) OVERRIDE {
88 NOTREACHED();
89 }
90
91 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {
92 if (!request->status().is_success()) {
93 callback_.Run(false);
94 return;
95 }
96 ReadFromBlob();
97 }
98
99 virtual void ReadFromBlob() {
100 int bytes_read;
101 bool done =
102 blob_request_->Read(buffer_.get(), buffer_->size(), &bytes_read);
103 if (done)
104 OnReadCompleted(blob_request_.get(), bytes_read);
105 }
106
107 virtual void OnReadCompleted(net::URLRequest* request,
108 int bytes_read) OVERRIDE {
109 if (!request->status().is_success()) {
110 callback_.Run(false);
111 return;
112 }
113
114 if (bytes_read == 0) {
115 callback_.Run(true); // what should we really return here?
116 return;
117 }
118
119 net::CompletionCallback cache_write_callback = base::Bind(
120 &BlobReader::DidWriteDataToEntry, base::Unretained(this), bytes_read);
121
122 LOG(ERROR) << "Writing: " << std::string(buffer_->data(), bytes_read);
123
124 int rv = entry_->WriteData(ServiceWorkerCache::INDEX_RESPONSE_BODY,
125 cache_entry_offset_,
126 buffer_,
127 bytes_read,
128 cache_write_callback,
129 false /* truncate */); // what should this be?
130 if (rv != net::ERR_IO_PENDING) {
131 DidWriteDataToEntry(bytes_read, rv);
132 }
133 }
134
135 void DidWriteDataToEntry(int expected_bytes, int rv) {
136 if (rv != expected_bytes) {
137 callback_.Run(false);
138 return;
139 }
140
141 cache_entry_offset_ += rv;
142 ReadFromBlob();
143 }
144
145 private:
146 int cache_entry_offset_;
147 disk_cache::Entry* entry_;
148 scoped_ptr<net::URLRequest> blob_request_;
149 BoolCallback callback_;
150 scoped_refptr<net::IOBufferWithSize> buffer_;
151 };
152
15 // static 153 // static
16 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache( 154 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreateMemoryCache(
17 const std::string& name, 155 const std::string& name,
18 net::URLRequestContext* request_context, 156 net::URLRequestContext* request_context,
19 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context) { 157 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context) {
20 return make_scoped_ptr(new ServiceWorkerCache( 158 return make_scoped_ptr(new ServiceWorkerCache(
21 base::FilePath(), name, request_context, blob_context)); 159 base::FilePath(), name, request_context, blob_context));
22 } 160 }
23 161
24 // static 162 // static
25 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache( 163 scoped_ptr<ServiceWorkerCache> ServiceWorkerCache::CreatePersistentCache(
26 const base::FilePath& path, 164 const base::FilePath& path,
27 const std::string& name, 165 const std::string& name,
28 net::URLRequestContext* request_context, 166 net::URLRequestContext* request_context,
29 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context) { 167 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context) {
30 return make_scoped_ptr( 168 return make_scoped_ptr(
31 new ServiceWorkerCache(path, name, request_context, blob_context)); 169 new ServiceWorkerCache(path, name, request_context, blob_context));
32 } 170 }
33 171
34 void ServiceWorkerCache::CreateBackend( 172 ServiceWorkerCache::~ServiceWorkerCache() {
35 const base::Callback<void(bool)>& callback) {
36 callback.Run(true);
37 } 173 }
38 174
39 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() { 175 base::WeakPtr<ServiceWorkerCache> ServiceWorkerCache::AsWeakPtr() {
40 return weak_ptr_factory_.GetWeakPtr(); 176 return weak_ptr_factory_.GetWeakPtr();
41 } 177 }
42 178
179 void ServiceWorkerCache::CreateBackend(const ErrorCallback& callback) {
180 net::CacheType cache_type =
181 path_.empty() ? net::MEMORY_CACHE : net::DISK_CACHE;
182
183 net::CompletionCallback create_cache_callback =
184 base::Bind(&ServiceWorkerCache::CreateBackendDidCreate,
185 base::Unretained(this),
186 callback);
187 int rv = disk_cache::CreateCacheBackend(
188 cache_type,
189 net::CACHE_BACKEND_SIMPLE,
190 path_,
191 kMaxCacheBytes,
192 true, /* force */
193 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
michaeln 2014/08/14 10:35:20 ServiceWorkerContextCore constructor has the cache
jkarlin 2014/08/14 19:53:32 Agree, added a TODO to do that in another CL.
194 NULL,
195 &backend_,
michaeln 2014/08/14 10:35:20 initialization is treacherous, i think if ServiceW
jkarlin 2014/08/14 19:53:33 The ServiceWorkerCacheStorage::Delete(cache) can't
michaeln1 2014/08/14 22:57:09 The callback won't get called but &backend_ is wri
jkarlin 2014/08/15 11:49:44 Done.
196 create_cache_callback);
197 if (rv != net::ERR_IO_PENDING)
198 CreateBackendDidCreate(callback, rv);
199 }
200
201 void ServiceWorkerCache::CreateBackendDidCreate(const ErrorCallback& callback,
202 int rv) {
203 if (rv != net::OK) {
204 callback.Run(ErrorTypeStorage);
205 return;
206 }
207 callback.Run(ErrorTypeOK);
208 }
209
210 void ServiceWorkerCache::Put(ServiceWorkerFetchRequest* request,
211 ServiceWorkerResponse* response,
212 const ErrorCallback& callback) {
213 DCHECK(backend_);
214
215 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
216
217 disk_cache::Entry** entry_ptr = entry.get();
218
219 net::CompletionCallback create_entry_callback =
220 base::Bind(&ServiceWorkerCache::PutDidCreateEntry,
221 base::Unretained(this),
222 request,
223 response,
224 callback,
225 base::Passed(entry.Pass()));
226
227 int rv = backend_->CreateEntry(
228 request->url.spec(), entry_ptr, create_entry_callback);
229
230 if (rv != net::ERR_IO_PENDING)
231 create_entry_callback.Run(rv);
232 }
233
234 void ServiceWorkerCache::Match(ServiceWorkerFetchRequest* request,
235 const ResponseCallback& callback) {
236 DCHECK(backend_);
237
238 scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
239
240 disk_cache::Entry** entry_ptr = entry.get();
241
242 net::CompletionCallback open_entry_callback =
243 base::Bind(&ServiceWorkerCache::MatchDidOpenEntry,
244 weak_ptr_factory_.GetWeakPtr(),
245 request,
246 callback,
247 base::Passed(entry.Pass()));
248
249 int rv =
250 backend_->OpenEntry(request->url.spec(), entry_ptr, open_entry_callback);
251 if (rv != net::ERR_IO_PENDING)
252 open_entry_callback.Run(rv);
253 }
254
255 void ServiceWorkerCache::MatchDidOpenEntry(
256 ServiceWorkerFetchRequest* request,
257 const ResponseCallback& callback,
258 scoped_ptr<disk_cache::Entry*> entryptr,
259 int rv) {
260 if (rv != net::OK) {
261 callback.Run(ErrorNotFound,
262 scoped_ptr<ServiceWorkerResponse>(),
263 scoped_ptr<webkit_blob::BlobDataHandle>());
264 return;
265 }
266
267 DCHECK(entryptr);
268 disk_cache::Entry* entry = *entryptr;
269
270 scoped_refptr<net::IOBufferWithSize> buffer(
271 new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS)));
272
273 int read_rv =
274 entry->ReadData(INDEX_HEADERS,
275 0,
276 buffer.get(),
277 buffer->size(),
278 base::Bind(&ServiceWorkerCache::MatchDidReadHeaderData,
279 weak_ptr_factory_.GetWeakPtr(),
280 request,
281 callback,
282 base::Unretained(entry),
michaeln 2014/08/14 10:35:20 if ServiceWorkerCache is deleted while in flight,
jkarlin 2014/08/14 19:53:32 Yes, thanks. Hadn't gotten to all of the pointers
283 buffer));
284 if (read_rv != net::ERR_IO_PENDING)
285 MatchDidReadHeaderData(request, callback, entry, buffer, read_rv);
286 }
287
288 void ServiceWorkerCache::MatchDidReadHeaderData(
289 ServiceWorkerFetchRequest* request,
290 const ResponseCallback& callback,
291 disk_cache::Entry* entry,
292 const scoped_refptr<net::IOBufferWithSize>& buffer,
293 int rv) {
294 if (rv != buffer->size()) {
295 entry->Close();
296 callback.Run(ErrorTypeStorage,
297 scoped_ptr<ServiceWorkerResponse>(),
298 scoped_ptr<webkit_blob::BlobDataHandle>());
299 return;
300 }
301
302 ServiceWorkerRequestResponseHeaders headers;
303
304 if (!headers.ParseFromArray(buffer->data(), buffer->size())) {
305 entry->Close();
306 callback.Run(ErrorTypeStorage,
307 scoped_ptr<ServiceWorkerResponse>(),
308 scoped_ptr<webkit_blob::BlobDataHandle>());
309 return;
310 }
311
312 scoped_ptr<ServiceWorkerResponse> response(
313 new ServiceWorkerResponse(request->url,
314 headers.status_code(),
315 headers.status_text(),
316 std::map<std::string, std::string>(),
317 ""));
318
319 for (int i = 0; i < headers.response_headers_size(); ++i) {
320 const ServiceWorkerRequestResponseHeaders::HeaderMap header =
321 headers.response_headers(i);
322 response->headers.insert(std::make_pair(header.name(), header.value()));
323 }
324
325 // TODO(jkarlin): Insert vary validation here.
326
327 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
328 entry->Close();
329 callback.Run(ErrorTypeOK,
330 response.Pass(),
331 scoped_ptr<webkit_blob::BlobDataHandle>());
332 return;
333 }
334
335 // Stream the response body into a blob.
336 if (!blob_storage_context_) {
337 entry->Close();
338 callback.Run(ErrorTypeStorage,
339 scoped_ptr<ServiceWorkerResponse>(),
340 scoped_ptr<webkit_blob::BlobDataHandle>());
341 return;
342 }
343
344 response->blob_uuid = base::GenerateGUID();
345
346 scoped_refptr<webkit_blob::BlobData> blob_data =
347 new webkit_blob::BlobData(response->blob_uuid);
348 scoped_refptr<net::IOBufferWithSize> response_body_buffer(
349 new net::IOBufferWithSize(kBufferSize));
350
351 scoped_ptr<ResponseReadContext> read_context(
352 new ResponseReadContext(response_body_buffer, blob_data));
353
354 net::CompletionCallback read_callback =
355 base::Bind(&ServiceWorkerCache::MatchDidReadResponseBodyData,
356 weak_ptr_factory_.GetWeakPtr(),
357 request,
358 callback,
359 base::Unretained(entry),
360 base::Passed(response.Pass()),
361 base::Passed(read_context.Pass()));
362
363 int read_rv = entry->ReadData(
364 INDEX_RESPONSE_BODY, 0, buffer.get(), buffer->size(), read_callback);
365
366 if (read_rv != net::ERR_IO_PENDING)
367 read_callback.Run(read_rv);
368 }
369
370 void ServiceWorkerCache::MatchDidReadResponseBodyData(
371 ServiceWorkerFetchRequest* request,
372 const ResponseCallback& callback,
373 disk_cache::Entry* entry,
374 scoped_ptr<ServiceWorkerResponse> response,
375 scoped_ptr<ResponseReadContext> response_context,
376 int rv) {
377 if (entry < 0) {
378 entry->Close();
379 callback.Run(ErrorTypeStorage,
380 scoped_ptr<ServiceWorkerResponse>(),
381 scoped_ptr<webkit_blob::BlobDataHandle>());
382 }
383
384 if (rv == 0) {
385 entry->Close();
386
387 MatchDoneWithBody(
388 request, callback, response.Pass(), response_context.Pass());
389 return;
390 }
391
392 // TODO(jkarlin): This copying of the the entire cache response into memory is
393 // awful. Create a new interface around SimpleCache that provides access the
394 // data directly from the file. See bug http://crbug.com/403493.
395 response_context->blob_data->AppendData(response_context->buffer->data(), rv);
396 response_context->total_bytes_read += rv;
397 int total_bytes_read = response_context->total_bytes_read;
398
399 LOG(ERROR) << "Reading: " << std::string(response_context->buffer->data(),
400 rv);
401 // Grab the pointer before response_context is Pass()ed.
402 net::IOBufferWithSize* buffer = response_context->buffer;
403
404 net::CompletionCallback read_callback =
405 base::Bind(&ServiceWorkerCache::MatchDidReadResponseBodyData,
406 weak_ptr_factory_.GetWeakPtr(),
407 request,
408 callback,
409 base::Unretained(entry),
410 base::Passed(response.Pass()),
411 base::Passed(response_context.Pass()));
412
413 int read_rv = entry->ReadData(INDEX_RESPONSE_BODY,
414 total_bytes_read,
415 buffer,
416 buffer->size(),
417 read_callback);
418
419 if (read_rv != net::ERR_IO_PENDING)
420 read_callback.Run(read_rv);
421 }
422
423 void ServiceWorkerCache::MatchDoneWithBody(
424 ServiceWorkerFetchRequest* request,
425 const ResponseCallback& callback,
426 scoped_ptr<ServiceWorkerResponse> response,
427 scoped_ptr<ResponseReadContext> response_context) {
428 // TODO(jkarlin): Create a blob and pass it back to the renderer. How do we
429 // reference count that?
michaeln 2014/08/14 10:35:20 1) the uuid is sent from browser->renderer in the
jkarlin 2014/08/14 19:53:32 Acknowledged.
430 if (!blob_storage_context_) {
431 callback.Run(ErrorTypeStorage,
432 scoped_ptr<ServiceWorkerResponse>(),
433 scoped_ptr<webkit_blob::BlobDataHandle>());
434 return;
435 }
436
437 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle(
438 blob_storage_context_->AddFinishedBlob(
439 response_context->blob_data.get()));
440
441 callback.Run(ErrorTypeOK, response.Pass(), blob_data_handle.Pass());
442 }
443
444 void ServiceWorkerCache::PutDidCreateEntry(
445 ServiceWorkerFetchRequest* request,
446 ServiceWorkerResponse* response,
447 const ErrorCallback& callback,
448 scoped_ptr<disk_cache::Entry*> entryptr,
449 int rv) {
450 if (rv != net::OK) {
451 callback.Run(ErrorTypeExists);
452 return;
453 }
454
455 DCHECK(entryptr);
456 disk_cache::Entry* entry = *entryptr;
457
458 ServiceWorkerRequestResponseHeaders headers;
459 headers.set_method(request->method);
460
461 headers.set_status_code(response->status_code);
462 headers.set_status_text(response->status_text);
463 for (std::map<std::string, std::string>::const_iterator it =
464 request->headers.begin();
465 it != request->headers.end();
466 ++it) {
467 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
468 headers.add_request_headers();
469 header_map->set_name(it->first);
470 header_map->set_value(it->second);
471 }
472
473 for (std::map<std::string, std::string>::const_iterator it =
474 response->headers.begin();
475 it != response->headers.end();
476 ++it) {
477 ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
478 headers.add_response_headers();
479 header_map->set_name(it->first);
480 header_map->set_value(it->second);
481 }
482
483 scoped_refptr<net::ZeroCopyStringIOBuffer> buffer(
michaeln 2014/08/14 10:35:20 would it make sense for the existing StringIOBuffe
jkarlin 2014/08/14 19:53:33 I like the idea of using std::string:swap. I chan
484 new net::ZeroCopyStringIOBuffer());
485 if (!headers.SerializeToString(buffer->string())) {
486 callback.Run(ErrorTypeStorage);
487 }
488
489 buffer->Done();
490
491 net::CompletionCallback write_headers_callback =
492 base::Bind(&ServiceWorkerCache::PutDidWriteHeaders,
493 weak_ptr_factory_.GetWeakPtr(),
494 request,
495 response,
496 callback,
497 entry,
498 buffer->string()->size());
499
500 rv = entry->WriteData(INDEX_HEADERS,
501 0 /* offset */,
502 buffer,
503 buffer->string()->size(),
504 write_headers_callback,
505 true /* truncate */);
506
507 if (rv != net::ERR_IO_PENDING)
508 write_headers_callback.Run(rv);
509 }
510
511 void ServiceWorkerCache::PutDidWriteHeaders(ServiceWorkerFetchRequest* request,
512 ServiceWorkerResponse* response,
513 const ErrorCallback& callback,
514 disk_cache::Entry* entry,
515 int expected_bytes,
516 int rv) {
517 if (rv != expected_bytes) {
518 entry->Doom();
519 entry->Close();
520 callback.Run(ErrorTypeStorage);
521 return;
522 }
523
524 // The metadata is written, now for the response content. The data is streamed
525 // from the blob into the cache entry.
526
527 if (response->blob_uuid.empty()) {
528 entry->Close();
529 callback.Run(ErrorTypeOK);
530 return;
531 }
532
533 if (!blob_storage_context_) {
534 entry->Doom();
535 entry->Close();
536 callback.Run(ErrorTypeStorage);
537 return;
538 }
539
540 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle =
541 blob_storage_context_->GetBlobDataFromUUID(response->blob_uuid);
michaeln 2014/08/14 10:35:20 you should get this handle up front in ServiceWork
jkarlin 2014/08/14 19:53:32 Thanks! Done and added test.
542
543 if (!blob_data_handle) {
544 entry->Doom();
545 entry->Close();
546 callback.Run(ErrorTypeStorage);
547 return;
548 }
549
550 scoped_ptr<BlobReader> reader(new BlobReader(entry));
551
552 reader->StreamBlobToCache(
553 request_context_,
554 blob_data_handle.Pass(),
555 base::Bind(&ServiceWorkerCache::PutDidWriteBlobToCache,
556 weak_ptr_factory_.GetWeakPtr(),
557 callback,
558 entry,
michaeln 2014/08/14 10:35:20 if ServiceWorkerCache is deleted prior to completi
jkarlin 2014/08/14 19:53:33 Done.
559 base::Passed(reader.Pass())));
560 }
561
562 void ServiceWorkerCache::PutDidWriteBlobToCache(
563 const ErrorCallback& callback,
564 disk_cache::Entry* entry,
565 scoped_ptr<BlobReader> blob_reader,
566 bool success) {
567 if (!success) {
568 entry->Doom();
569 entry->Close();
570 callback.Run(ErrorTypeStorage);
571 return;
572 }
573
574 entry->Close();
575 callback.Run(ErrorTypeOK);
576 }
577
43 ServiceWorkerCache::ServiceWorkerCache( 578 ServiceWorkerCache::ServiceWorkerCache(
44 const base::FilePath& path, 579 const base::FilePath& path,
45 const std::string& name, 580 const std::string& name,
46 net::URLRequestContext* request_context, 581 net::URLRequestContext* request_context,
47 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context) 582 base::WeakPtr<webkit_blob::BlobStorageContext> blob_context)
48 : path_(path), 583 : path_(path),
49 name_(name), 584 name_(name),
50 request_context_(request_context), 585 request_context_(request_context),
51 blob_storage_context_(blob_context), 586 blob_storage_context_(blob_context),
52 id_(0), 587 id_(0),
53 weak_ptr_factory_(this) { 588 weak_ptr_factory_(this) {
54 } 589 }
55 590
56 ServiceWorkerCache::~ServiceWorkerCache() {
57 }
58
59 } // namespace content 591 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_cache.h ('k') | content/browser/service_worker/service_worker_cache.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698