| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/appcache/web_application_cache_host_impl.h" | 5 #include "webkit/appcache/web_application_cache_host_impl.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/id_map.h" | 8 #include "base/id_map.h" |
| 9 #include "base/string_util.h" |
| 9 #include "webkit/api/public/WebURL.h" | 10 #include "webkit/api/public/WebURL.h" |
| 10 #include "webkit/api/public/WebURLRequest.h" | 11 #include "webkit/api/public/WebURLRequest.h" |
| 11 #include "webkit/api/public/WebURLResponse.h" | 12 #include "webkit/api/public/WebURLResponse.h" |
| 12 | 13 |
| 13 using WebKit::WebApplicationCacheHost; | 14 using WebKit::WebApplicationCacheHost; |
| 14 using WebKit::WebApplicationCacheHostClient; | 15 using WebKit::WebApplicationCacheHostClient; |
| 15 using WebKit::WebURLRequest; | 16 using WebKit::WebURLRequest; |
| 16 using WebKit::WebURL; | 17 using WebKit::WebURL; |
| 17 using WebKit::WebURLResponse; | 18 using WebKit::WebURLResponse; |
| 18 | 19 |
| 19 namespace appcache { | 20 namespace appcache { |
| 20 | 21 |
| 21 static IDMap<WebApplicationCacheHostImpl> all_hosts; | 22 static IDMap<WebApplicationCacheHostImpl> all_hosts; |
| 22 | 23 |
| 23 WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { | 24 WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { |
| 24 return all_hosts.Lookup(id); | 25 return all_hosts.Lookup(id); |
| 25 } | 26 } |
| 26 | 27 |
| 27 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( | 28 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( |
| 28 WebApplicationCacheHostClient* client, | 29 WebApplicationCacheHostClient* client, |
| 29 AppCacheBackend* backend) | 30 AppCacheBackend* backend) |
| 30 : client_(client), | 31 : client_(client), |
| 31 backend_(backend), | 32 backend_(backend), |
| 32 ALLOW_THIS_IN_INITIALIZER_LIST(host_id_(all_hosts.Add(this))), | 33 ALLOW_THIS_IN_INITIALIZER_LIST(host_id_(all_hosts.Add(this))), |
| 33 has_status_(false), | 34 has_status_(false), |
| 34 status_(UNCACHED), | 35 status_(UNCACHED), |
| 35 has_cached_status_(false), | 36 has_cached_status_(false), |
| 36 cached_status_(UNCACHED), | 37 cached_status_(UNCACHED), |
| 37 is_in_http_family_(false), | 38 is_scheme_supported_(false), |
| 38 should_capture_main_response_(MAYBE) { | 39 is_get_method_(false), |
| 40 is_new_master_entry_(MAYBE) { |
| 39 DCHECK(client && backend && (host_id_ != kNoHostId)); | 41 DCHECK(client && backend && (host_id_ != kNoHostId)); |
| 40 | 42 |
| 41 backend_->RegisterHost(host_id_); | 43 backend_->RegisterHost(host_id_); |
| 42 } | 44 } |
| 43 | 45 |
| 44 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { | 46 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { |
| 45 backend_->UnregisterHost(host_id_); | 47 backend_->UnregisterHost(host_id_); |
| 46 all_hosts.Remove(host_id_); | 48 all_hosts.Remove(host_id_); |
| 47 } | 49 } |
| 48 | 50 |
| 49 void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id, | 51 void WebApplicationCacheHostImpl::OnCacheSelected(int64 selected_cache_id, |
| 50 appcache::Status status) { | 52 appcache::Status status) { |
| 51 status_ = status; | 53 status_ = status; |
| 52 has_status_ = true; | 54 has_status_ = true; |
| 53 } | 55 } |
| 54 | 56 |
| 55 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { | 57 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { |
| 56 if (has_status_) | 58 if (has_status_) |
| 57 status_ = status; | 59 status_ = status; |
| 58 } | 60 } |
| 59 | 61 |
| 60 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { | 62 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { |
| 61 client_->notifyEventListener(static_cast<EventID>(event_id)); | 63 client_->notifyEventListener(static_cast<EventID>(event_id)); |
| 62 } | 64 } |
| 63 | 65 |
| 64 void WebApplicationCacheHostImpl::willStartMainResourceRequest( | 66 void WebApplicationCacheHostImpl::willStartMainResourceRequest( |
| 65 WebURLRequest& request) { | 67 WebURLRequest& request) { |
| 66 request.setAppCacheHostID(host_id_); | 68 request.setAppCacheHostID(host_id_); |
| 69 std::string method = request.httpMethod().utf8(); |
| 70 is_get_method_ = (method == kHttpGETMethod); |
| 71 DCHECK(method == StringToUpperASCII(method)); |
| 67 } | 72 } |
| 68 | 73 |
| 69 void WebApplicationCacheHostImpl::willStartSubResourceRequest( | 74 void WebApplicationCacheHostImpl::willStartSubResourceRequest( |
| 70 WebURLRequest& request) { | 75 WebURLRequest& request) { |
| 71 request.setAppCacheHostID(host_id_); | 76 request.setAppCacheHostID(host_id_); |
| 72 } | 77 } |
| 73 | 78 |
| 74 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { | 79 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { |
| 75 // Reset any previous status values we've received from the backend | 80 // Reset any previous status values we've received from the backend |
| 76 // since we're now selecting a new cache. | 81 // since we're now selecting a new cache. |
| 77 has_status_ = false; | 82 has_status_ = false; |
| 78 has_cached_status_ = false; | 83 has_cached_status_ = false; |
| 79 should_capture_main_response_ = NO; | 84 is_new_master_entry_ = NO; |
| 80 backend_->SelectCache(host_id_, main_response_url_, | 85 backend_->SelectCache(host_id_, document_url_, |
| 81 main_response_.appCacheID(), | 86 document_response_.appCacheID(), |
| 82 GURL()); | 87 GURL()); |
| 83 } | 88 } |
| 84 | 89 |
| 85 bool WebApplicationCacheHostImpl::selectCacheWithManifest( | 90 bool WebApplicationCacheHostImpl::selectCacheWithManifest( |
| 86 const WebURL& manifest_url) { | 91 const WebURL& manifest_url) { |
| 87 // Reset any previous status values we've received from the backend | 92 // Reset any previous status values we've received from the backend |
| 88 // since we're now selecting a new cache. | 93 // since we're now selecting a new cache. |
| 89 has_status_ = false; | 94 has_status_ = false; |
| 90 has_cached_status_ = false; | 95 has_cached_status_ = false; |
| 91 | 96 |
| 92 GURL manifest_gurl(manifest_url); | 97 GURL manifest_gurl(manifest_url); |
| 93 if (manifest_gurl.has_ref()) { | 98 if (manifest_gurl.has_ref()) { |
| 94 GURL::Replacements replacements; | 99 GURL::Replacements replacements; |
| 95 replacements.ClearRef(); | 100 replacements.ClearRef(); |
| 96 manifest_gurl = manifest_gurl.ReplaceComponents(replacements); | 101 manifest_gurl = manifest_gurl.ReplaceComponents(replacements); |
| 97 } | 102 } |
| 98 | 103 |
| 104 // 6.9.6 The application cache selection algorithm |
| 99 // Check for new 'master' entries. | 105 // Check for new 'master' entries. |
| 100 if (main_response_.appCacheID() == kNoCacheId) { | 106 if (document_response_.appCacheID() == kNoCacheId) { |
| 101 should_capture_main_response_ = is_in_http_family_ ? YES : NO; | 107 if (is_scheme_supported_ && is_get_method_ && |
| 102 backend_->SelectCache(host_id_, main_response_url_, | 108 (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { |
| 109 is_new_master_entry_ = YES; |
| 110 } else { |
| 111 is_new_master_entry_ = NO; |
| 112 manifest_gurl = GURL::EmptyGURL(); |
| 113 } |
| 114 backend_->SelectCache(host_id_, document_url_, |
| 103 kNoCacheId, manifest_gurl); | 115 kNoCacheId, manifest_gurl); |
| 104 return true; | 116 return true; |
| 105 } | 117 } |
| 106 | 118 |
| 107 DCHECK(should_capture_main_response_ == NO); | 119 DCHECK(is_new_master_entry_ = NO); |
| 108 | 120 |
| 121 // 6.9.6 The application cache selection algorithm |
| 109 // Check for 'foreign' entries. | 122 // Check for 'foreign' entries. |
| 110 GURL main_response_manifest_gurl(main_response_.appCacheManifestURL()); | 123 GURL document_manifest_gurl(document_response_.appCacheManifestURL()); |
| 111 if (main_response_manifest_gurl != manifest_gurl) { | 124 if (document_manifest_gurl != manifest_gurl) { |
| 112 backend_->MarkAsForeignEntry(host_id_, main_response_url_, | 125 backend_->MarkAsForeignEntry(host_id_, document_url_, |
| 113 main_response_.appCacheID()); | 126 document_response_.appCacheID()); |
| 114 has_cached_status_ = true; | 127 has_cached_status_ = true; |
| 115 cached_status_ = UNCACHED; | 128 cached_status_ = UNCACHED; |
| 116 return false; // the navigation will be restarted | 129 return false; // the navigation will be restarted |
| 117 } | 130 } |
| 118 | 131 |
| 119 // Its a 'master' entry thats already in the cache. | 132 // Its a 'master' entry thats already in the cache. |
| 120 backend_->SelectCache(host_id_, main_response_url_, | 133 backend_->SelectCache(host_id_, document_url_, |
| 121 main_response_.appCacheID(), | 134 document_response_.appCacheID(), |
| 122 manifest_gurl); | 135 manifest_gurl); |
| 123 return true; | 136 return true; |
| 124 } | 137 } |
| 125 | 138 |
| 126 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( | 139 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( |
| 127 const WebURLResponse& response) { | 140 const WebURLResponse& response) { |
| 128 main_response_ = response; | 141 document_response_ = response; |
| 129 main_response_url_ = main_response_.url(); | 142 document_url_ = document_response_.url(); |
| 130 is_in_http_family_ = main_response_url_.SchemeIs("http") || | 143 is_scheme_supported_ = IsSchemeSupported(document_url_); |
| 131 main_response_url_.SchemeIs("https"); | 144 if ((document_response_.appCacheID() != kNoCacheId) || |
| 132 if ((main_response_.appCacheID() != kNoCacheId) || !is_in_http_family_) | 145 !is_scheme_supported_ || !is_get_method_) |
| 133 should_capture_main_response_ = NO; | 146 is_new_master_entry_ = NO; |
| 134 } | 147 } |
| 135 | 148 |
| 136 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( | 149 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( |
| 137 const char* data, int len) { | 150 const char* data, int len) { |
| 138 if (should_capture_main_response_ == NO) | 151 if (is_new_master_entry_ == NO) |
| 139 return; | 152 return; |
| 140 // TODO(michaeln): write me | 153 // TODO(michaeln): write me |
| 141 } | 154 } |
| 142 | 155 |
| 143 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { | 156 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { |
| 144 if (should_capture_main_response_ == NO) | 157 if (is_new_master_entry_ == NO) |
| 145 return; | 158 return; |
| 146 // TODO(michaeln): write me | 159 // TODO(michaeln): write me |
| 147 } | 160 } |
| 148 | 161 |
| 149 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { | 162 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { |
| 150 // We're careful about the status value to avoid race conditions. | 163 // We're careful about the status value to avoid race conditions. |
| 151 // | 164 // |
| 152 // Generally the webappcachehost sends an async stream of messages to the | 165 // Generally the webappcachehost sends an async stream of messages to the |
| 153 // backend, and receives an asyncronous stream of events from the backend. | 166 // backend, and receives an asyncronous stream of events from the backend. |
| 154 // In the backend, all operations are serialized and as state changes | 167 // In the backend, all operations are serialized and as state changes |
| (...skipping 19 matching lines...) Expand all Loading... |
| 174 | 187 |
| 175 bool WebApplicationCacheHostImpl::startUpdate() { | 188 bool WebApplicationCacheHostImpl::startUpdate() { |
| 176 return backend_->StartUpdate(host_id_); | 189 return backend_->StartUpdate(host_id_); |
| 177 } | 190 } |
| 178 | 191 |
| 179 bool WebApplicationCacheHostImpl::swapCache() { | 192 bool WebApplicationCacheHostImpl::swapCache() { |
| 180 return backend_->SwapCache(host_id_); | 193 return backend_->SwapCache(host_id_); |
| 181 } | 194 } |
| 182 | 195 |
| 183 } // appcache namespace | 196 } // appcache namespace |
| OLD | NEW |