web_application_cache_host_impl.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 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)
5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "content/child/appcache/web_application_cache_host_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/id_map.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h"
11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "third_party/WebKit/public/platform/WebString.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebApplicationCacheHost;
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebApplicationCacheHostClient;
18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing blink::WebString;
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest;
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURL;
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLResponse;
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebVector;
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing appcache::AppCacheBackend;
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochusing appcache::AppCacheResourceInfo;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace content {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: the order of the elements in this array must match those
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the EventID enum in appcache_interfaces.h.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kEventNames[] = {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Checking", "Error", "NoUpdate", "Downloading", "Progress",
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "UpdateReady", "Cached", "Obsolete"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef IDMap<WebApplicationCacheHostImpl> HostsMap;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostsMap* all_hosts() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HostsMap* map = new HostsMap;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return map;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ClearUrlRef(const GURL& url) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.has_ref())
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return url;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL::Replacements replacements;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  replacements.ClearRef();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url.ReplaceComponents(replacements);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anon namespace
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return all_hosts()->Lookup(id);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebApplicationCacheHostClient* client,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheBackend* backend)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : client_(client),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_(backend),
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_id_(all_hosts()->Add(this)),
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_(appcache::APPCACHE_STATUS_UNCACHED),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_scheme_supported_(false),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_get_method_(false),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_(MAYBE),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_select_cache_called_(false) {
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(client && backend && (host_id_ != appcache::kAppCacheNoHostId));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->RegisterHost(host_id_);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->UnregisterHost(host_id_);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  all_hosts()->Remove(host_id_);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnCacheSelected(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const appcache::AppCacheInfo& info) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_info_ = info;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->didChangeCacheAssociation();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WebApplicationCacheHostImpl::OnStatusChanged(
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    appcache::AppCacheStatus status) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): delete me, not used
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WebApplicationCacheHostImpl::OnEventRaised(
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    appcache::AppCacheEventID event_id) {
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(event_id !=
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         appcache::APPCACHE_PROGRESS_EVENT);  // See OnProgressEventRaised.
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(event_id != appcache::APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache %s event";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message = base::StringPrintf(kFormatString,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           kEventNames[event_id]);
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnLogMessage(appcache::APPCACHE_LOG_INFO, message);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event_id) {
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_CHECKING_EVENT:
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_CHECKING;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_DOWNLOADING_EVENT:
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_DOWNLOADING;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_UPDATE_READY_EVENT:
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_UPDATE_READY;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_CACHED_EVENT:
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_NO_UPDATE_EVENT:
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_IDLE;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case appcache::APPCACHE_OBSOLETE_EVENT:
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_OBSOLETE;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->notifyEventListener(static_cast<EventID>(event_id));
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnProgressEventRaised(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, int num_total, int num_complete) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache Progress event (%d of %d) %s";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message = base::StringPrintf(kFormatString, num_complete,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           num_total, url.spec().c_str());
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnLogMessage(appcache::APPCACHE_LOG_INFO, message);
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  status_ = appcache::APPCACHE_STATUS_DOWNLOADING;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->notifyProgressEventListener(url, num_total, num_complete);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnErrorEventRaised(
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const appcache::AppCacheErrorDetails& details) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache Error event: %s";
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  std::string full_message =
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      base::StringPrintf(kFormatString, details.message.c_str());
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnLogMessage(appcache::APPCACHE_LOG_ERROR, full_message);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  status_ = cache_info_.is_complete ? appcache::APPCACHE_STATUS_IDLE :
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      appcache::APPCACHE_STATUS_UNCACHED;
151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (details.is_cross_origin) {
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Don't leak detailed information to script for cross-origin resources.
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_EQ(appcache::APPCACHE_RESOURCE_ERROR, details.reason);
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    client_->notifyErrorEventListener(
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        static_cast<ErrorReason>(details.reason), details.url, 0, WebString());
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  } else {
157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    client_->notifyErrorEventListener(static_cast<ErrorReason>(details.reason),
158e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      details.url,
159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      details.status,
160e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      WebString::fromUTF8(details.message));
161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::willStartMainResourceRequest(
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WebURLRequest& request, const WebApplicationCacheHost* spawning_host) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setAppCacheHostID(host_id_);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_main_resource_url_ = ClearUrlRef(request.url());
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string method = request.httpMethod().utf8();
171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  is_get_method_ = (method == appcache::kHttpGETMethod);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(method == StringToUpperASCII(method));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const WebApplicationCacheHostImpl* spawning_host_impl =
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<const WebApplicationCacheHostImpl*>(spawning_host);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (spawning_host_impl && (spawning_host_impl != this) &&
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      (spawning_host_impl->status_ != appcache::APPCACHE_STATUS_UNCACHED)) {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    backend_->SetSpawningHostId(host_id_, spawning_host_impl->host_id());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::willStartSubResourceRequest(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLRequest& request) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setAppCacheHostID(host_id_);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::selectCacheWithoutManifest() {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_select_cache_called_)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_select_cache_called_ = true;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  status_ = (document_response_.appCacheID() == appcache::kAppCacheNoCacheId) ?
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      appcache::APPCACHE_STATUS_UNCACHED : appcache::APPCACHE_STATUS_CHECKING;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_new_master_entry_ = NO;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SelectCache(host_id_, document_url_,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        document_response_.appCacheID(),
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        GURL());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::selectCacheWithManifest(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURL& manifest_url) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_select_cache_called_)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_select_cache_called_ = true;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL manifest_gurl(ClearUrlRef(manifest_url));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for new 'master' entries.
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (document_response_.appCacheID() == appcache::kAppCacheNoCacheId) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_scheme_supported_ && is_get_method_ &&
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) {
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_CHECKING;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_ = YES;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ = appcache::APPCACHE_STATUS_UNCACHED;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_ = NO;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manifest_gurl = GURL();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    backend_->SelectCache(
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        host_id_, document_url_, appcache::kAppCacheNoCacheId, manifest_gurl);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(NO, is_new_master_entry_);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for 'foreign' entries.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL document_manifest_gurl(document_response_.appCacheManifestURL());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_manifest_gurl != manifest_gurl) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->MarkAsForeignEntry(host_id_, document_url_,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 document_response_.appCacheID());
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    status_ = appcache::APPCACHE_STATUS_UNCACHED;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // the navigation will be restarted
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  status_ = appcache::APPCACHE_STATUS_CHECKING;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Its a 'master' entry thats already in the cache.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SelectCache(host_id_, document_url_,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        document_response_.appCacheID(),
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        manifest_gurl);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didReceiveResponseForMainResource(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURLResponse& response) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_response_ = response;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_url_ = ClearUrlRef(document_response_.url());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_url_ != original_main_resource_url_)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_get_method_ = true;  // A redirect was involved.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_main_resource_url_ = GURL();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  is_scheme_supported_ =  appcache::IsSchemeSupported(document_url_);
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if ((document_response_.appCacheID() != appcache::kAppCacheNoCacheId) ||
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !is_scheme_supported_ || !is_get_method_)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_new_master_entry_ = NO;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didReceiveDataForMainResource(
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* data, int len) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_new_master_entry_ == NO)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): write me
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_new_master_entry_ == NO)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): write me
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<WebApplicationCacheHost::Status>(status_);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::startUpdate() {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!backend_->StartUpdate(host_id_))
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (status_ == appcache::APPCACHE_STATUS_IDLE ||
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      status_ == appcache::APPCACHE_STATUS_UPDATE_READY)
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    status_ = appcache::APPCACHE_STATUS_CHECKING;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = backend_->GetStatus(host_id_);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::swapCache() {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!backend_->SwapCache(host_id_))
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status_ = backend_->GetStatus(host_id_);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::getAssociatedCacheInfo(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebApplicationCacheHost::CacheInfo* info) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->manifestURL = cache_info_.manifest_url;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache_info_.is_complete)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->creationTime = cache_info_.creation_time.ToDoubleT();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->updateTime = cache_info_.last_update_time.ToDoubleT();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->totalSize = cache_info_.size;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::getResourceList(
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebVector<ResourceInfo>* resources) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache_info_.is_complete)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<AppCacheResourceInfo> resource_infos;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->GetResourceList(host_id_, &resource_infos);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebVector<ResourceInfo> web_resources(resource_infos.size());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < resource_infos.size(); ++i) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].size = resource_infos[i].size;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isMaster = resource_infos[i].is_master;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isExplicit = resource_infos[i].is_explicit;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isManifest = resource_infos[i].is_manifest;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isForeign = resource_infos[i].is_foreign;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isFallback = resource_infos[i].is_fallback;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].url = resource_infos[i].url;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resources->swap(web_resources);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace content
326