OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer/appcache/web_application_cache_host_impl.h" | 5 #include "content/child/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/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "third_party/WebKit/public/web/WebDataSource.h" | |
12 #include "third_party/WebKit/public/web/WebFrame.h" | |
13 #include "third_party/WebKit/public/platform/WebURL.h" | 11 #include "third_party/WebKit/public/platform/WebURL.h" |
14 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 12 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
15 #include "third_party/WebKit/public/platform/WebURLResponse.h" | 13 #include "third_party/WebKit/public/platform/WebURLResponse.h" |
| 14 #include "third_party/WebKit/public/web/WebDataSource.h" |
| 15 #include "third_party/WebKit/public/web/WebFrame.h" |
16 | 16 |
17 using WebKit::WebApplicationCacheHost; | 17 using WebKit::WebApplicationCacheHost; |
18 using WebKit::WebApplicationCacheHostClient; | 18 using WebKit::WebApplicationCacheHostClient; |
19 using WebKit::WebDataSource; | 19 using WebKit::WebDataSource; |
20 using WebKit::WebFrame; | 20 using WebKit::WebFrame; |
21 using WebKit::WebURLRequest; | 21 using WebKit::WebURLRequest; |
22 using WebKit::WebURL; | 22 using WebKit::WebURL; |
23 using WebKit::WebURLResponse; | 23 using WebKit::WebURLResponse; |
24 using WebKit::WebVector; | 24 using WebKit::WebVector; |
| 25 using appcache::AppCacheBackend; |
| 26 using appcache::AppCacheResourceInfo; |
25 | 27 |
26 namespace appcache { | 28 namespace content { |
27 | 29 |
28 namespace { | 30 namespace { |
29 | 31 |
30 // Note: the order of the elements in this array must match those | 32 // Note: the order of the elements in this array must match those |
31 // of the EventID enum in appcache_interfaces.h. | 33 // of the EventID enum in appcache_interfaces.h. |
32 const char* kEventNames[] = { | 34 const char* kEventNames[] = { |
33 "Checking", "Error", "NoUpdate", "Downloading", "Progress", | 35 "Checking", "Error", "NoUpdate", "Downloading", "Progress", |
34 "UpdateReady", "Cached", "Obsolete" | 36 "UpdateReady", "Cached", "Obsolete" |
35 }; | 37 }; |
36 | 38 |
(...skipping 28 matching lines...) Expand all Loading... |
65 return static_cast<WebApplicationCacheHostImpl*> | 67 return static_cast<WebApplicationCacheHostImpl*> |
66 (data_source->applicationCacheHost()); | 68 (data_source->applicationCacheHost()); |
67 } | 69 } |
68 | 70 |
69 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( | 71 WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( |
70 WebApplicationCacheHostClient* client, | 72 WebApplicationCacheHostClient* client, |
71 AppCacheBackend* backend) | 73 AppCacheBackend* backend) |
72 : client_(client), | 74 : client_(client), |
73 backend_(backend), | 75 backend_(backend), |
74 host_id_(all_hosts()->Add(this)), | 76 host_id_(all_hosts()->Add(this)), |
75 status_(UNCACHED), | 77 status_(appcache::UNCACHED), |
76 is_scheme_supported_(false), | 78 is_scheme_supported_(false), |
77 is_get_method_(false), | 79 is_get_method_(false), |
78 is_new_master_entry_(MAYBE), | 80 is_new_master_entry_(MAYBE), |
79 was_select_cache_called_(false) { | 81 was_select_cache_called_(false) { |
80 DCHECK(client && backend && (host_id_ != kNoHostId)); | 82 DCHECK(client && backend && (host_id_ != appcache::kNoHostId)); |
81 | 83 |
82 backend_->RegisterHost(host_id_); | 84 backend_->RegisterHost(host_id_); |
83 } | 85 } |
84 | 86 |
85 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { | 87 WebApplicationCacheHostImpl::~WebApplicationCacheHostImpl() { |
86 backend_->UnregisterHost(host_id_); | 88 backend_->UnregisterHost(host_id_); |
87 all_hosts()->Remove(host_id_); | 89 all_hosts()->Remove(host_id_); |
88 } | 90 } |
89 | 91 |
90 void WebApplicationCacheHostImpl::OnCacheSelected( | 92 void WebApplicationCacheHostImpl::OnCacheSelected( |
91 const appcache::AppCacheInfo& info) { | 93 const appcache::AppCacheInfo& info) { |
92 cache_info_ = info; | 94 cache_info_ = info; |
93 client_->didChangeCacheAssociation(); | 95 client_->didChangeCacheAssociation(); |
94 } | 96 } |
95 | 97 |
96 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { | 98 void WebApplicationCacheHostImpl::OnStatusChanged(appcache::Status status) { |
97 // TODO(michaeln): delete me, not used | 99 // TODO(michaeln): delete me, not used |
98 } | 100 } |
99 | 101 |
100 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { | 102 void WebApplicationCacheHostImpl::OnEventRaised(appcache::EventID event_id) { |
101 DCHECK(event_id != PROGRESS_EVENT); // See OnProgressEventRaised. | 103 DCHECK(event_id != appcache::PROGRESS_EVENT); // See OnProgressEventRaised. |
102 DCHECK(event_id != ERROR_EVENT); // See OnErrorEventRaised. | 104 DCHECK(event_id != appcache::ERROR_EVENT); // See OnErrorEventRaised. |
103 | 105 |
104 // Emit logging output prior to calling out to script as we can get | 106 // Emit logging output prior to calling out to script as we can get |
105 // deleted within the script event handler. | 107 // deleted within the script event handler. |
106 const char* kFormatString = "Application Cache %s event"; | 108 const char* kFormatString = "Application Cache %s event"; |
107 std::string message = base::StringPrintf(kFormatString, | 109 std::string message = base::StringPrintf(kFormatString, |
108 kEventNames[event_id]); | 110 kEventNames[event_id]); |
109 OnLogMessage(LOG_INFO, message); | 111 OnLogMessage(appcache::LOG_INFO, message); |
110 | 112 |
111 switch (event_id) { | 113 switch (event_id) { |
112 case CHECKING_EVENT: | 114 case appcache::CHECKING_EVENT: |
113 status_ = CHECKING; | 115 status_ = appcache::CHECKING; |
114 break; | 116 break; |
115 case DOWNLOADING_EVENT: | 117 case appcache::DOWNLOADING_EVENT: |
116 status_ = DOWNLOADING; | 118 status_ = appcache::DOWNLOADING; |
117 break; | 119 break; |
118 case UPDATE_READY_EVENT: | 120 case appcache::UPDATE_READY_EVENT: |
119 status_ = UPDATE_READY; | 121 status_ = appcache::UPDATE_READY; |
120 break; | 122 break; |
121 case CACHED_EVENT: | 123 case appcache::CACHED_EVENT: |
122 case NO_UPDATE_EVENT: | 124 case appcache::NO_UPDATE_EVENT: |
123 status_ = IDLE; | 125 status_ = appcache::IDLE; |
124 break; | 126 break; |
125 case OBSOLETE_EVENT: | 127 case appcache::OBSOLETE_EVENT: |
126 status_ = OBSOLETE; | 128 status_ = appcache::OBSOLETE; |
127 break; | 129 break; |
128 default: | 130 default: |
129 NOTREACHED(); | 131 NOTREACHED(); |
130 break; | 132 break; |
131 } | 133 } |
132 | 134 |
133 client_->notifyEventListener(static_cast<EventID>(event_id)); | 135 client_->notifyEventListener(static_cast<EventID>(event_id)); |
134 } | 136 } |
135 | 137 |
136 void WebApplicationCacheHostImpl::OnProgressEventRaised( | 138 void WebApplicationCacheHostImpl::OnProgressEventRaised( |
137 const GURL& url, int num_total, int num_complete) { | 139 const GURL& url, int num_total, int num_complete) { |
138 // Emit logging output prior to calling out to script as we can get | 140 // Emit logging output prior to calling out to script as we can get |
139 // deleted within the script event handler. | 141 // deleted within the script event handler. |
140 const char* kFormatString = "Application Cache Progress event (%d of %d) %s"; | 142 const char* kFormatString = "Application Cache Progress event (%d of %d) %s"; |
141 std::string message = base::StringPrintf(kFormatString, num_complete, | 143 std::string message = base::StringPrintf(kFormatString, num_complete, |
142 num_total, url.spec().c_str()); | 144 num_total, url.spec().c_str()); |
143 OnLogMessage(LOG_INFO, message); | 145 OnLogMessage(appcache::LOG_INFO, message); |
144 status_ = DOWNLOADING; | 146 status_ = appcache::DOWNLOADING; |
145 client_->notifyProgressEventListener(url, num_total, num_complete); | 147 client_->notifyProgressEventListener(url, num_total, num_complete); |
146 } | 148 } |
147 | 149 |
148 void WebApplicationCacheHostImpl::OnErrorEventRaised( | 150 void WebApplicationCacheHostImpl::OnErrorEventRaised( |
149 const std::string& message) { | 151 const std::string& message) { |
150 // Emit logging output prior to calling out to script as we can get | 152 // Emit logging output prior to calling out to script as we can get |
151 // deleted within the script event handler. | 153 // deleted within the script event handler. |
152 const char* kFormatString = "Application Cache Error event: %s"; | 154 const char* kFormatString = "Application Cache Error event: %s"; |
153 std::string full_message = base::StringPrintf(kFormatString, | 155 std::string full_message = base::StringPrintf(kFormatString, |
154 message.c_str()); | 156 message.c_str()); |
155 OnLogMessage(LOG_ERROR, full_message); | 157 OnLogMessage(appcache::LOG_ERROR, full_message); |
156 | 158 |
157 status_ = cache_info_.is_complete ? IDLE : UNCACHED; | 159 status_ = cache_info_.is_complete ? appcache::IDLE : appcache::UNCACHED; |
158 client_->notifyEventListener(static_cast<EventID>(ERROR_EVENT)); | 160 client_->notifyEventListener(static_cast<EventID>(appcache::ERROR_EVENT)); |
159 } | 161 } |
160 | 162 |
161 void WebApplicationCacheHostImpl::willStartMainResourceRequest( | 163 void WebApplicationCacheHostImpl::willStartMainResourceRequest( |
162 WebURLRequest& request, const WebFrame* frame) { | 164 WebURLRequest& request, const WebFrame* frame) { |
163 request.setAppCacheHostID(host_id_); | 165 request.setAppCacheHostID(host_id_); |
164 | 166 |
165 original_main_resource_url_ = ClearUrlRef(request.url()); | 167 original_main_resource_url_ = ClearUrlRef(request.url()); |
166 | 168 |
167 std::string method = request.httpMethod().utf8(); | 169 std::string method = request.httpMethod().utf8(); |
168 is_get_method_ = (method == kHttpGETMethod); | 170 is_get_method_ = (method == appcache::kHttpGETMethod); |
169 DCHECK(method == StringToUpperASCII(method)); | 171 DCHECK(method == StringToUpperASCII(method)); |
170 | 172 |
171 if (frame) { | 173 if (frame) { |
172 const WebFrame* spawning_frame = frame->parent(); | 174 const WebFrame* spawning_frame = frame->parent(); |
173 if (!spawning_frame) | 175 if (!spawning_frame) |
174 spawning_frame = frame->opener(); | 176 spawning_frame = frame->opener(); |
175 if (!spawning_frame) | 177 if (!spawning_frame) |
176 spawning_frame = frame; | 178 spawning_frame = frame; |
177 | 179 |
178 WebApplicationCacheHostImpl* spawning_host = FromFrame(spawning_frame); | 180 WebApplicationCacheHostImpl* spawning_host = FromFrame(spawning_frame); |
179 if (spawning_host && (spawning_host != this) && | 181 if (spawning_host && (spawning_host != this) && |
180 (spawning_host->status_ != UNCACHED)) { | 182 (spawning_host->status_ != appcache::UNCACHED)) { |
181 backend_->SetSpawningHostId(host_id_, spawning_host->host_id()); | 183 backend_->SetSpawningHostId(host_id_, spawning_host->host_id()); |
182 } | 184 } |
183 } | 185 } |
184 } | 186 } |
185 | 187 |
186 void WebApplicationCacheHostImpl::willStartSubResourceRequest( | 188 void WebApplicationCacheHostImpl::willStartSubResourceRequest( |
187 WebURLRequest& request) { | 189 WebURLRequest& request) { |
188 request.setAppCacheHostID(host_id_); | 190 request.setAppCacheHostID(host_id_); |
189 } | 191 } |
190 | 192 |
191 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { | 193 void WebApplicationCacheHostImpl::selectCacheWithoutManifest() { |
192 if (was_select_cache_called_) | 194 if (was_select_cache_called_) |
193 return; | 195 return; |
194 was_select_cache_called_ = true; | 196 was_select_cache_called_ = true; |
195 | 197 |
196 status_ = (document_response_.appCacheID() == kNoCacheId) ? | 198 status_ = (document_response_.appCacheID() == appcache::kNoCacheId) ? |
197 UNCACHED : CHECKING; | 199 appcache::UNCACHED : appcache::CHECKING; |
198 is_new_master_entry_ = NO; | 200 is_new_master_entry_ = NO; |
199 backend_->SelectCache(host_id_, document_url_, | 201 backend_->SelectCache(host_id_, document_url_, |
200 document_response_.appCacheID(), | 202 document_response_.appCacheID(), |
201 GURL()); | 203 GURL()); |
202 } | 204 } |
203 | 205 |
204 bool WebApplicationCacheHostImpl::selectCacheWithManifest( | 206 bool WebApplicationCacheHostImpl::selectCacheWithManifest( |
205 const WebURL& manifest_url) { | 207 const WebURL& manifest_url) { |
206 if (was_select_cache_called_) | 208 if (was_select_cache_called_) |
207 return true; | 209 return true; |
208 was_select_cache_called_ = true; | 210 was_select_cache_called_ = true; |
209 | 211 |
210 GURL manifest_gurl(ClearUrlRef(manifest_url)); | 212 GURL manifest_gurl(ClearUrlRef(manifest_url)); |
211 | 213 |
212 // 6.9.6 The application cache selection algorithm | 214 // 6.9.6 The application cache selection algorithm |
213 // Check for new 'master' entries. | 215 // Check for new 'master' entries. |
214 if (document_response_.appCacheID() == kNoCacheId) { | 216 if (document_response_.appCacheID() == appcache::kNoCacheId) { |
215 if (is_scheme_supported_ && is_get_method_ && | 217 if (is_scheme_supported_ && is_get_method_ && |
216 (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { | 218 (manifest_gurl.GetOrigin() == document_url_.GetOrigin())) { |
217 status_ = CHECKING; | 219 status_ = appcache::CHECKING; |
218 is_new_master_entry_ = YES; | 220 is_new_master_entry_ = YES; |
219 } else { | 221 } else { |
220 status_ = UNCACHED; | 222 status_ = appcache::UNCACHED; |
221 is_new_master_entry_ = NO; | 223 is_new_master_entry_ = NO; |
222 manifest_gurl = GURL(); | 224 manifest_gurl = GURL(); |
223 } | 225 } |
224 backend_->SelectCache(host_id_, document_url_, | 226 backend_->SelectCache( |
225 kNoCacheId, manifest_gurl); | 227 host_id_, document_url_, appcache::kNoCacheId, manifest_gurl); |
226 return true; | 228 return true; |
227 } | 229 } |
228 | 230 |
229 DCHECK_EQ(NO, is_new_master_entry_); | 231 DCHECK_EQ(NO, is_new_master_entry_); |
230 | 232 |
231 // 6.9.6 The application cache selection algorithm | 233 // 6.9.6 The application cache selection algorithm |
232 // Check for 'foreign' entries. | 234 // Check for 'foreign' entries. |
233 GURL document_manifest_gurl(document_response_.appCacheManifestURL()); | 235 GURL document_manifest_gurl(document_response_.appCacheManifestURL()); |
234 if (document_manifest_gurl != manifest_gurl) { | 236 if (document_manifest_gurl != manifest_gurl) { |
235 backend_->MarkAsForeignEntry(host_id_, document_url_, | 237 backend_->MarkAsForeignEntry(host_id_, document_url_, |
236 document_response_.appCacheID()); | 238 document_response_.appCacheID()); |
237 status_ = UNCACHED; | 239 status_ = appcache::UNCACHED; |
238 return false; // the navigation will be restarted | 240 return false; // the navigation will be restarted |
239 } | 241 } |
240 | 242 |
241 status_ = CHECKING; | 243 status_ = appcache::CHECKING; |
242 | 244 |
243 // Its a 'master' entry thats already in the cache. | 245 // Its a 'master' entry thats already in the cache. |
244 backend_->SelectCache(host_id_, document_url_, | 246 backend_->SelectCache(host_id_, document_url_, |
245 document_response_.appCacheID(), | 247 document_response_.appCacheID(), |
246 manifest_gurl); | 248 manifest_gurl); |
247 return true; | 249 return true; |
248 } | 250 } |
249 | 251 |
250 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( | 252 void WebApplicationCacheHostImpl::didReceiveResponseForMainResource( |
251 const WebURLResponse& response) { | 253 const WebURLResponse& response) { |
252 document_response_ = response; | 254 document_response_ = response; |
253 document_url_ = ClearUrlRef(document_response_.url()); | 255 document_url_ = ClearUrlRef(document_response_.url()); |
254 if (document_url_ != original_main_resource_url_) | 256 if (document_url_ != original_main_resource_url_) |
255 is_get_method_ = true; // A redirect was involved. | 257 is_get_method_ = true; // A redirect was involved. |
256 original_main_resource_url_ = GURL(); | 258 original_main_resource_url_ = GURL(); |
257 | 259 |
258 is_scheme_supported_ = IsSchemeSupported(document_url_); | 260 is_scheme_supported_ = appcache::IsSchemeSupported(document_url_); |
259 if ((document_response_.appCacheID() != kNoCacheId) || | 261 if ((document_response_.appCacheID() != appcache::kNoCacheId) || |
260 !is_scheme_supported_ || !is_get_method_) | 262 !is_scheme_supported_ || !is_get_method_) |
261 is_new_master_entry_ = NO; | 263 is_new_master_entry_ = NO; |
262 } | 264 } |
263 | 265 |
264 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( | 266 void WebApplicationCacheHostImpl::didReceiveDataForMainResource( |
265 const char* data, int len) { | 267 const char* data, int len) { |
266 if (is_new_master_entry_ == NO) | 268 if (is_new_master_entry_ == NO) |
267 return; | 269 return; |
268 // TODO(michaeln): write me | 270 // TODO(michaeln): write me |
269 } | 271 } |
270 | 272 |
271 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { | 273 void WebApplicationCacheHostImpl::didFinishLoadingMainResource(bool success) { |
272 if (is_new_master_entry_ == NO) | 274 if (is_new_master_entry_ == NO) |
273 return; | 275 return; |
274 // TODO(michaeln): write me | 276 // TODO(michaeln): write me |
275 } | 277 } |
276 | 278 |
277 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { | 279 WebApplicationCacheHost::Status WebApplicationCacheHostImpl::status() { |
278 return static_cast<WebApplicationCacheHost::Status>(status_); | 280 return static_cast<WebApplicationCacheHost::Status>(status_); |
279 } | 281 } |
280 | 282 |
281 bool WebApplicationCacheHostImpl::startUpdate() { | 283 bool WebApplicationCacheHostImpl::startUpdate() { |
282 if (!backend_->StartUpdate(host_id_)) | 284 if (!backend_->StartUpdate(host_id_)) |
283 return false; | 285 return false; |
284 if (status_ == IDLE || status_ == UPDATE_READY) | 286 if (status_ == appcache::IDLE || status_ == appcache::UPDATE_READY) |
285 status_ = CHECKING; | 287 status_ = appcache::CHECKING; |
286 else | 288 else |
287 status_ = backend_->GetStatus(host_id_); | 289 status_ = backend_->GetStatus(host_id_); |
288 return true; | 290 return true; |
289 } | 291 } |
290 | 292 |
291 bool WebApplicationCacheHostImpl::swapCache() { | 293 bool WebApplicationCacheHostImpl::swapCache() { |
292 if (!backend_->SwapCache(host_id_)) | 294 if (!backend_->SwapCache(host_id_)) |
293 return false; | 295 return false; |
294 status_ = backend_->GetStatus(host_id_); | 296 status_ = backend_->GetStatus(host_id_); |
295 return true; | 297 return true; |
(...skipping 22 matching lines...) Expand all Loading... |
318 web_resources[i].isMaster = resource_infos[i].is_master; | 320 web_resources[i].isMaster = resource_infos[i].is_master; |
319 web_resources[i].isExplicit = resource_infos[i].is_explicit; | 321 web_resources[i].isExplicit = resource_infos[i].is_explicit; |
320 web_resources[i].isManifest = resource_infos[i].is_manifest; | 322 web_resources[i].isManifest = resource_infos[i].is_manifest; |
321 web_resources[i].isForeign = resource_infos[i].is_foreign; | 323 web_resources[i].isForeign = resource_infos[i].is_foreign; |
322 web_resources[i].isFallback = resource_infos[i].is_fallback; | 324 web_resources[i].isFallback = resource_infos[i].is_fallback; |
323 web_resources[i].url = resource_infos[i].url; | 325 web_resources[i].url = resource_infos[i].url; |
324 } | 326 } |
325 resources->swap(web_resources); | 327 resources->swap(web_resources); |
326 } | 328 } |
327 | 329 |
328 } // appcache namespace | 330 } // namespace content |
OLD | NEW |