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;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace content {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: the order of the elements in this array must match those
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the EventID enum in appcache_interfaces.h.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kEventNames[] = {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "Checking", "Error", "NoUpdate", "Downloading", "Progress",
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "UpdateReady", "Cached", "Obsolete"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef IDMap<WebApplicationCacheHostImpl> HostsMap;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostsMap* all_hosts() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HostsMap* map = new HostsMap;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return map;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ClearUrlRef(const GURL& url) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.has_ref())
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return url;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL::Replacements replacements;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  replacements.ClearRef();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url.ReplaceComponents(replacements);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anon namespace
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return all_hosts()->Lookup(id);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebApplicationCacheHostClient* client,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheBackend* backend)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : client_(client),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      backend_(backend),
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_id_(all_hosts()->Add(this)),
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_(APPCACHE_STATUS_UNCACHED),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_scheme_supported_(false),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_get_method_(false),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_(MAYBE),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      was_select_cache_called_(false) {
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(client && backend && (host_id_ != kAppCacheNoHostId));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->RegisterHost(host_id_);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->UnregisterHost(host_id_);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  all_hosts()->Remove(host_id_);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnCacheSelected(
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AppCacheInfo& info) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache_info_ = info;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->didChangeCacheAssociation();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WebApplicationCacheHostImpl::OnStatusChanged(
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppCacheStatus status) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): delete me, not used
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WebApplicationCacheHostImpl::OnEventRaised(
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppCacheEventID event_id) {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(event_id !=
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         APPCACHE_PROGRESS_EVENT);  // See OnProgressEventRaised.
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(event_id != APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache %s event";
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message = base::StringPrintf(kFormatString,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           kEventNames[event_id]);
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnLogMessage(APPCACHE_LOG_INFO, message);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event_id) {
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_CHECKING_EVENT:
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_CHECKING;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_DOWNLOADING_EVENT:
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_DOWNLOADING;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_UPDATE_READY_EVENT:
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_UPDATE_READY;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_CACHED_EVENT:
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_NO_UPDATE_EVENT:
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_IDLE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case APPCACHE_OBSOLETE_EVENT:
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_OBSOLETE;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->notifyEventListener(static_cast<EventID>(event_id));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnProgressEventRaised(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, int num_total, int num_complete) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache Progress event (%d of %d) %s";
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string message = base::StringPrintf(kFormatString, num_complete,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           num_total, url.spec().c_str());
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnLogMessage(APPCACHE_LOG_INFO, message);
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status_ = APPCACHE_STATUS_DOWNLOADING;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_->notifyProgressEventListener(url, num_total, num_complete);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::OnErrorEventRaised(
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const AppCacheErrorDetails& details) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit logging output prior to calling out to script as we can get
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleted within the script event handler.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kFormatString = "Application Cache Error event: %s";
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  std::string full_message =
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      base::StringPrintf(kFormatString, details.message.c_str());
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnLogMessage(APPCACHE_LOG_ERROR, full_message);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status_ = cache_info_.is_complete ? APPCACHE_STATUS_IDLE :
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      APPCACHE_STATUS_UNCACHED;
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (details.is_cross_origin) {
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Don't leak detailed information to script for cross-origin resources.
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(APPCACHE_RESOURCE_ERROR, details.reason);
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    client_->notifyErrorEventListener(
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        static_cast<ErrorReason>(details.reason), details.url, 0, WebString());
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  } else {
155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    client_->notifyErrorEventListener(static_cast<ErrorReason>(details.reason),
156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      details.url,
157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      details.status,
158e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                      WebString::fromUTF8(details.message));
159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::willStartMainResourceRequest(
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WebURLRequest& request, const WebApplicationCacheHost* spawning_host) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setAppCacheHostID(host_id_);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_main_resource_url_ = ClearUrlRef(request.url());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string method = request.httpMethod().utf8();
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  is_get_method_ = (method == kHttpGETMethod);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(method == StringToUpperASCII(method));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const WebApplicationCacheHostImpl* spawning_host_impl =
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<const WebApplicationCacheHostImpl*>(spawning_host);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (spawning_host_impl && (spawning_host_impl != this) &&
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (spawning_host_impl->status_ != APPCACHE_STATUS_UNCACHED)) {
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    backend_->SetSpawningHostId(host_id_, spawning_host_impl->host_id());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::willStartSubResourceRequest(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebURLRequest& request) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.setAppCacheHostID(host_id_);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::selectCacheWithoutManifest() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_select_cache_called_)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_select_cache_called_ = true;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status_ = (document_response_.appCacheID() == kAppCacheNoCacheId) ?
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      APPCACHE_STATUS_UNCACHED : APPCACHE_STATUS_CHECKING;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_new_master_entry_ = NO;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SelectCache(host_id_, document_url_,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        document_response_.appCacheID(),
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        GURL());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::selectCacheWithManifest(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURL& manifest_url) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (was_select_cache_called_)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  was_select_cache_called_ = true;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL manifest_gurl(ClearUrlRef(manifest_url));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for new 'master' entries.
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (document_response_.appCacheID() == kAppCacheNoCacheId) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_scheme_supported_ && is_get_method_ &&
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) {
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_CHECKING;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_ = YES;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ = APPCACHE_STATUS_UNCACHED;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_new_master_entry_ = NO;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manifest_gurl = GURL();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    backend_->SelectCache(
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        host_id_, document_url_, kAppCacheNoCacheId, manifest_gurl);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(NO, is_new_master_entry_);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 6.9.6 The application cache selection algorithm
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for 'foreign' entries.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL document_manifest_gurl(document_response_.appCacheManifestURL());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_manifest_gurl != manifest_gurl) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_->MarkAsForeignEntry(host_id_, document_url_,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 document_response_.appCacheID());
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    status_ = APPCACHE_STATUS_UNCACHED;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // the navigation will be restarted
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  status_ = APPCACHE_STATUS_CHECKING;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Its a 'master' entry thats already in the cache.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->SelectCache(host_id_, document_url_,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        document_response_.appCacheID(),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        manifest_gurl);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didReceiveResponseForMainResource(
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebURLResponse& response) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_response_ = response;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_url_ = ClearUrlRef(document_response_.url());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_url_ != original_main_resource_url_)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_get_method_ = true;  // A redirect was involved.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_main_resource_url_ = GURL();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  is_scheme_supported_ =  IsSchemeSupportedForAppCache(document_url_);
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if ((document_response_.appCacheID() != kAppCacheNoCacheId) ||
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !is_scheme_supported_ || !is_get_method_)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_new_master_entry_ = NO;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didReceiveDataForMainResource(
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* data, int len) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_new_master_entry_ == NO)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): write me
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_new_master_entry_ == NO)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): write me
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<WebApplicationCacheHost::Status>(status_);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::startUpdate() {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!backend_->StartUpdate(host_id_))
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (status_ == APPCACHE_STATUS_IDLE ||
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      status_ == APPCACHE_STATUS_UPDATE_READY)
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    status_ = APPCACHE_STATUS_CHECKING;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status_ = backend_->GetStatus(host_id_);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebApplicationCacheHostImpl::swapCache() {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!backend_->SwapCache(host_id_))
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  status_ = backend_->GetStatus(host_id_);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::getAssociatedCacheInfo(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebApplicationCacheHost::CacheInfo* info) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->manifestURL = cache_info_.manifest_url;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache_info_.is_complete)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->creationTime = cache_info_.creation_time.ToDoubleT();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->updateTime = cache_info_.last_update_time.ToDoubleT();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info->totalSize = cache_info_.size;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebApplicationCacheHostImpl::getResourceList(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebVector<ResourceInfo>* resources) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!cache_info_.is_complete)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<AppCacheResourceInfo> resource_infos;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_->GetResourceList(host_id_, &resource_infos);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebVector<ResourceInfo> web_resources(resource_infos.size());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < resource_infos.size(); ++i) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].size = resource_infos[i].size;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isMaster = resource_infos[i].is_master;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isExplicit = resource_infos[i].is_explicit;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isManifest = resource_infos[i].is_manifest;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isForeign = resource_infos[i].is_foreign;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].isFallback = resource_infos[i].is_fallback;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_resources[i].url = resource_infos[i].url;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resources->swap(web_resources);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
323ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace content
324