15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/stl_util.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_executable_handler.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_group.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_host.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_storage.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/appcache_interfaces.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AppCache::AppCache(AppCacheStorage* storage, int64 cache_id)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cache_id_(cache_id),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owning_group_(NULL),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      online_whitelist_all_(false),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_complete_(false),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cache_size_(0),
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      storage_(storage) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  storage_->working_set()->AddCache(this);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCache::~AppCache() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(associated_hosts_.empty());
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (owning_group_.get()) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(is_complete_);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owning_group_->RemoveCache(this);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!owning_group_.get());
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  storage_->working_set()->RemoveCache(this);
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  STLDeleteContainerPairSecondPointers(
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      executable_handlers_.begin(), executable_handlers_.end());
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::UnassociateHost(AppCacheHost* host) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  associated_hosts_.erase(host);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::AddEntry(const GURL& url, const AppCacheEntry& entry) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entries_.find(url) == entries_.end());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_.insert(EntryMap::value_type(url, entry));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_size_ += entry.response_size();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCache::AddOrModifyEntry(const GURL& url, const AppCacheEntry& entry) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::pair<EntryMap::iterator, bool> ret =
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries_.insert(EntryMap::value_type(url, entry));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Entry already exists.  Merge the types of the new and existing entries.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ret.second)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret.first->second.add_types(entry.types());
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache_size_ += entry.response_size();  // New entry. Add to cache size.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret.second;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::RemoveEntry(const GURL& url) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryMap::iterator found = entries_.find(url);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(found != entries_.end());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_size_ -= found->second.response_size();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_.erase(found);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheEntry* AppCache::GetEntry(const GURL& url) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryMap::iterator it = entries_.find(url);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (it != entries_.end()) ? &(it->second) : NULL;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const AppCacheEntry* AppCache::GetEntryAndUrlWithResponseId(
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 response_id, GURL* optional_url_out) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (EntryMap::const_iterator iter = entries_.begin();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter !=  entries_.end(); ++iter) {
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (iter->second.response_id() == response_id) {
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (optional_url_out)
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        *optional_url_out = iter->first;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &iter->second;
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AppCacheExecutableHandler* AppCache::GetExecutableHandler(int64 response_id) {
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HandlerMap::const_iterator found = executable_handlers_.find(response_id);
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (found != executable_handlers_.end())
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return found->second;
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)AppCacheExecutableHandler* AppCache::GetOrCreateExecutableHandler(
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64 response_id, net::IOBuffer* handler_source) {
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppCacheExecutableHandler* handler = GetExecutableHandler(response_id);
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (handler)
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return handler;
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL handler_url;
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const AppCacheEntry* entry = GetEntryAndUrlWithResponseId(
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      response_id, &handler_url);
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!entry || !entry->IsExecutable())
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(storage_->service()->handler_factory());
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<AppCacheExecutableHandler> own_ptr =
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      storage_->service()->handler_factory()->
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          CreateHandler(handler_url, handler_source);
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  handler = own_ptr.release();
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!handler)
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  executable_handlers_[response_id] = handler;
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return handler;
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
118116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGURL AppCache::GetNamespaceEntryUrl(const AppCacheNamespaceVector& namespaces,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const GURL& namespace_url) const {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = namespaces.size();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < count; ++i) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (namespaces[i].namespace_url == namespace_url)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return namespaces[i].target_url;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SortNamespacesByLength(
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AppCacheNamespace& lhs, const AppCacheNamespace& rhs) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return lhs.namespace_url.spec().length() > rhs.namespace_url.spec().length();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppCache::InitializeWithManifest(AppCacheManifest* manifest) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(manifest);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  intercept_namespaces_.swap(manifest->intercept_namespaces);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fallback_namespaces_.swap(manifest->fallback_namespaces);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  online_whitelist_namespaces_.swap(manifest->online_whitelist_namespaces);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  online_whitelist_all_ = manifest->online_whitelist_all;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sort the namespaces by url string length, longest to shortest,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since longer matches trump when matching a url to a namespace.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(intercept_namespaces_.begin(), intercept_namespaces_.end(),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SortNamespacesByLength);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(fallback_namespaces_.begin(), fallback_namespaces_.end(),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SortNamespacesByLength);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::InitializeWithDatabaseRecords(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheDatabase::CacheRecord& cache_record,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<AppCacheDatabase::EntryRecord>& entries,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<AppCacheDatabase::NamespaceRecord>& intercepts,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<AppCacheDatabase::NamespaceRecord>& fallbacks,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cache_id_ == cache_record.cache_id);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  online_whitelist_all_ = cache_record.online_wildcard;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_time_ = cache_record.update_time;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < entries.size(); ++i) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheDatabase::EntryRecord& entry = entries.at(i);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEntry(entry.url, AppCacheEntry(entry.flags, entry.response_id,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      entry.response_size));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cache_size_ == cache_record.cache_size);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < intercepts.size(); ++i)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    intercept_namespaces_.push_back(intercepts.at(i).namespace_);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < fallbacks.size(); ++i)
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fallback_namespaces_.push_back(fallbacks.at(i).namespace_);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sort the fallback namespaces by url string length, longest to shortest,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since longer matches trump when matching a url to a namespace.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(intercept_namespaces_.begin(), intercept_namespaces_.end(),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SortNamespacesByLength);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(fallback_namespaces_.begin(), fallback_namespaces_.end(),
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SortNamespacesByLength);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < whitelists.size(); ++i) {
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const AppCacheDatabase::OnlineWhiteListRecord& record = whitelists.at(i);
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    online_whitelist_namespaces_.push_back(
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        AppCacheNamespace(APPCACHE_NETWORK_NAMESPACE,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  record.namespace_url,
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  GURL(),
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  record.is_pattern));
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::ToDatabaseRecords(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheGroup* group,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDatabase::CacheRecord* cache_record,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<AppCacheDatabase::EntryRecord>* entries,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<AppCacheDatabase::NamespaceRecord>* intercepts,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<AppCacheDatabase::NamespaceRecord>* fallbacks,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(group && cache_record && entries && fallbacks && whitelists);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(entries->empty() && fallbacks->empty() && whitelists->empty());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_record->cache_id = cache_id_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_record->group_id = group->group_id();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_record->online_wildcard = online_whitelist_all_;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_record->update_time = update_time_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_record->cache_size = 0;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (EntryMap::const_iterator iter = entries_.begin();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != entries_.end(); ++iter) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entries->push_back(AppCacheDatabase::EntryRecord());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDatabase::EntryRecord& record = entries->back();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.url = iter->first;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.cache_id = cache_id_;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.flags = iter->second.types();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.response_id = iter->second.response_id();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.response_size = iter->second.response_size();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache_record->cache_size += record.response_size;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin = group->manifest_url().GetOrigin();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < intercept_namespaces_.size(); ++i) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    intercepts->push_back(AppCacheDatabase::NamespaceRecord());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDatabase::NamespaceRecord& record = intercepts->back();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.cache_id = cache_id_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.origin = origin;
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    record.namespace_ = intercept_namespaces_[i];
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < fallback_namespaces_.size(); ++i) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallbacks->push_back(AppCacheDatabase::NamespaceRecord());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDatabase::NamespaceRecord& record = fallbacks->back();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.cache_id = cache_id_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.origin = origin;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    record.namespace_ = fallback_namespaces_[i];
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < online_whitelist_namespaces_.size(); ++i) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    whitelists->push_back(AppCacheDatabase::OnlineWhiteListRecord());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheDatabase::OnlineWhiteListRecord& record = whitelists->back();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    record.cache_id = cache_id_;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    record.namespace_url = online_whitelist_namespaces_[i].namespace_url;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    record.is_pattern = online_whitelist_namespaces_[i].is_pattern;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppCache::FindResponseForRequest(const GURL& url,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheEntry* found_entry, GURL* found_intercept_namespace,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheEntry* found_fallback_entry, GURL* found_fallback_namespace,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* found_network_namespace) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore fragments when looking up URL in the cache.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_no_ref;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.has_ref()) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL::Replacements replacements;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    replacements.ClearRef();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_no_ref = url.ReplaceComponents(replacements);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_no_ref = url;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.6.6 Changes to the networking model
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheEntry* entry = GetEntry(url_no_ref);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_entry = *entry;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  *found_network_namespace = IsInNetworkNamespace(url_no_ref);
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (*found_network_namespace)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AppCacheNamespace* intercept_namespace =
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FindInterceptNamespace(url_no_ref);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (intercept_namespace) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = GetEntry(intercept_namespace->target_url);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(entry);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_entry = *entry;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_intercept_namespace = intercept_namespace->namespace_url;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AppCacheNamespace* fallback_namespace =
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FindFallbackNamespace(url_no_ref);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fallback_namespace) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry = GetEntry(fallback_namespace->target_url);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(entry);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_fallback_entry = *entry;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_fallback_namespace = fallback_namespace->namespace_url;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *found_network_namespace = online_whitelist_all_;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *found_network_namespace;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCache::ToResourceInfoVector(AppCacheResourceInfoVector* infos) const {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(infos && infos->empty());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (EntryMap::const_iterator iter = entries_.begin();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter !=  entries_.end(); ++iter) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    infos->push_back(AppCacheResourceInfo());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheResourceInfo& info = infos->back();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.url = iter->first;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_master = iter->second.IsMaster();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_manifest = iter->second.IsManifest();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_intercept = iter->second.IsIntercept();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_fallback = iter->second.IsFallback();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_foreign = iter->second.IsForeign();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.is_explicit = iter->second.IsExplicit();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.size = iter->second.response_size();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.response_id = iter->second.response_id();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst AppCacheNamespace* AppCache::FindNamespace(
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AppCacheNamespaceVector& namespaces,
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& url) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count = namespaces.size();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < count; ++i) {
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (namespaces[i].IsMatch(url))
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return &namespaces[i];
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
328