| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/mock_appcache_storage.h" | 5 #include "webkit/appcache/mock_appcache_storage.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 // This layer of indirection is here to facilitate testing. | 114 // This layer of indirection is here to facilitate testing. |
| 115 if (simulate_find_sub_resource_) { | 115 if (simulate_find_sub_resource_) { |
| 116 *found_entry = simulated_found_entry_; | 116 *found_entry = simulated_found_entry_; |
| 117 *found_fallback_entry = simulated_found_fallback_entry_; | 117 *found_fallback_entry = simulated_found_fallback_entry_; |
| 118 *found_network_namespace = simulated_found_network_namespace_; | 118 *found_network_namespace = simulated_found_network_namespace_; |
| 119 simulate_find_sub_resource_ = false; | 119 simulate_find_sub_resource_ = false; |
| 120 return; | 120 return; |
| 121 } | 121 } |
| 122 | 122 |
| 123 GURL fallback_namespace_not_used; | 123 GURL fallback_namespace_not_used; |
| 124 GURL intercept_namespace_not_used; |
| 124 cache->FindResponseForRequest( | 125 cache->FindResponseForRequest( |
| 125 url, found_entry, found_fallback_entry, | 126 url, found_entry, &intercept_namespace_not_used, |
| 126 &fallback_namespace_not_used, found_network_namespace); | 127 found_fallback_entry, &fallback_namespace_not_used, |
| 128 found_network_namespace); |
| 127 } | 129 } |
| 128 | 130 |
| 129 void MockAppCacheStorage::MarkEntryAsForeign( | 131 void MockAppCacheStorage::MarkEntryAsForeign( |
| 130 const GURL& entry_url, int64 cache_id) { | 132 const GURL& entry_url, int64 cache_id) { |
| 131 AppCache* cache = working_set_.GetCache(cache_id); | 133 AppCache* cache = working_set_.GetCache(cache_id); |
| 132 if (cache) { | 134 if (cache) { |
| 133 AppCacheEntry* entry = cache->GetEntry(entry_url); | 135 AppCacheEntry* entry = cache->GetEntry(entry_url); |
| 134 DCHECK(entry); | 136 DCHECK(entry); |
| 135 if (entry) | 137 if (entry) |
| 136 entry->add_types(AppCacheEntry::FOREIGN); | 138 entry->add_types(AppCacheEntry::FOREIGN); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 RemoveStoredCaches(copy); | 227 RemoveStoredCaches(copy); |
| 226 } | 228 } |
| 227 | 229 |
| 228 if (delegate) | 230 if (delegate) |
| 229 delegate->OnGroupAndNewestCacheStored(group, newest_cache, true, false); | 231 delegate->OnGroupAndNewestCacheStored(group, newest_cache, true, false); |
| 230 } | 232 } |
| 231 | 233 |
| 232 namespace { | 234 namespace { |
| 233 | 235 |
| 234 struct FoundCandidate { | 236 struct FoundCandidate { |
| 235 GURL url; | 237 GURL namespace_entry_url; |
| 236 AppCacheEntry entry; | 238 AppCacheEntry entry; |
| 237 int64 cache_id; | 239 int64 cache_id; |
| 238 int64 group_id; | 240 int64 group_id; |
| 239 GURL manifest_url; | 241 GURL manifest_url; |
| 240 bool is_cache_in_use; | 242 bool is_cache_in_use; |
| 241 | 243 |
| 242 FoundCandidate() | 244 FoundCandidate() |
| 243 : cache_id(kNoCacheId), group_id(0), is_cache_in_use(false) {} | 245 : cache_id(kNoCacheId), group_id(0), is_cache_in_use(false) {} |
| 244 }; | 246 }; |
| 245 | 247 |
| 248 void MaybeTakeNewNamespaceEntry( |
| 249 NamespaceType namespace_type, |
| 250 const AppCacheEntry &entry, |
| 251 const GURL& namespace_url, |
| 252 bool cache_is_in_use, |
| 253 FoundCandidate* best_candidate, |
| 254 GURL* best_candidate_namespace, |
| 255 AppCache* cache, |
| 256 AppCacheGroup* group) { |
| 257 DCHECK(entry.has_response_id()); |
| 258 |
| 259 bool take_new_entry = true; |
| 260 |
| 261 // Does the new candidate entry trump our current best candidate? |
| 262 if (best_candidate->entry.has_response_id()) { |
| 263 // Longer namespace prefix matches win. |
| 264 size_t candidate_length = |
| 265 namespace_url.spec().length(); |
| 266 size_t best_length = |
| 267 best_candidate_namespace->spec().length(); |
| 268 |
| 269 if (candidate_length > best_length) { |
| 270 take_new_entry = true; |
| 271 } else if (candidate_length == best_length && |
| 272 cache_is_in_use && !best_candidate->is_cache_in_use) { |
| 273 take_new_entry = true; |
| 274 } else { |
| 275 take_new_entry = false; |
| 276 } |
| 277 } |
| 278 |
| 279 if (take_new_entry) { |
| 280 if (namespace_type == FALLBACK_NAMESPACE) { |
| 281 best_candidate->namespace_entry_url = |
| 282 cache->GetFallbackEntryUrl(namespace_url); |
| 283 } else { |
| 284 best_candidate->namespace_entry_url = |
| 285 cache->GetInterceptEntryUrl(namespace_url); |
| 286 } |
| 287 best_candidate->entry = entry; |
| 288 best_candidate->cache_id = cache->cache_id(); |
| 289 best_candidate->group_id = group->group_id(); |
| 290 best_candidate->manifest_url = group->manifest_url(); |
| 291 best_candidate->is_cache_in_use = cache_is_in_use; |
| 292 *best_candidate_namespace = namespace_url; |
| 293 } |
| 294 } |
| 246 } // namespace | 295 } // namespace |
| 247 | 296 |
| 248 void MockAppCacheStorage::ProcessFindResponseForMainRequest( | 297 void MockAppCacheStorage::ProcessFindResponseForMainRequest( |
| 249 const GURL& url, scoped_refptr<DelegateReference> delegate_ref) { | 298 const GURL& url, scoped_refptr<DelegateReference> delegate_ref) { |
| 250 if (simulate_find_main_resource_) { | 299 if (simulate_find_main_resource_) { |
| 251 simulate_find_main_resource_ = false; | 300 simulate_find_main_resource_ = false; |
| 252 if (delegate_ref->delegate) { | 301 if (delegate_ref->delegate) { |
| 253 delegate_ref->delegate->OnMainResponseFound( | 302 delegate_ref->delegate->OnMainResponseFound( |
| 254 url, simulated_found_entry_, | 303 url, simulated_found_entry_, |
| 255 simulated_found_fallback_url_, simulated_found_fallback_entry_, | 304 simulated_found_fallback_url_, simulated_found_fallback_entry_, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 266 | 315 |
| 267 // TODO(michaeln): The heuristics around choosing amoungst | 316 // TODO(michaeln): The heuristics around choosing amoungst |
| 268 // multiple candidates is under specified, and just plain | 317 // multiple candidates is under specified, and just plain |
| 269 // not fully understood. Refine these over time. In particular, | 318 // not fully understood. Refine these over time. In particular, |
| 270 // * prefer candidates from newer caches | 319 // * prefer candidates from newer caches |
| 271 // * take into account the cache associated with the document | 320 // * take into account the cache associated with the document |
| 272 // that initiated the navigation | 321 // that initiated the navigation |
| 273 // * take into account the cache associated with the document | 322 // * take into account the cache associated with the document |
| 274 // currently residing in the frame being navigated | 323 // currently residing in the frame being navigated |
| 275 FoundCandidate found_candidate; | 324 FoundCandidate found_candidate; |
| 325 GURL found_intercept_candidate_namespace; |
| 276 FoundCandidate found_fallback_candidate; | 326 FoundCandidate found_fallback_candidate; |
| 277 GURL found_fallback_candidate_namespace; | 327 GURL found_fallback_candidate_namespace; |
| 278 | 328 |
| 279 for (StoredGroupMap::const_iterator it = stored_groups_.begin(); | 329 for (StoredGroupMap::const_iterator it = stored_groups_.begin(); |
| 280 it != stored_groups_.end(); ++it) { | 330 it != stored_groups_.end(); ++it) { |
| 281 AppCacheGroup* group = it->second.get(); | 331 AppCacheGroup* group = it->second.get(); |
| 282 AppCache* cache = group->newest_complete_cache(); | 332 AppCache* cache = group->newest_complete_cache(); |
| 283 if (group->is_obsolete() || !cache || | 333 if (group->is_obsolete() || !cache || |
| 284 (url.GetOrigin() != group->manifest_url().GetOrigin())) { | 334 (url.GetOrigin() != group->manifest_url().GetOrigin())) { |
| 285 continue; | 335 continue; |
| 286 } | 336 } |
| 287 | 337 |
| 288 AppCacheEntry found_entry; | 338 AppCacheEntry found_entry; |
| 289 AppCacheEntry found_fallback_entry; | 339 AppCacheEntry found_fallback_entry; |
| 340 GURL found_intercept_namespace; |
| 290 GURL found_fallback_namespace; | 341 GURL found_fallback_namespace; |
| 291 bool ignore_found_network_namespace = false; | 342 bool ignore_found_network_namespace = false; |
| 292 bool found = cache->FindResponseForRequest( | 343 bool found = cache->FindResponseForRequest( |
| 293 url, &found_entry, &found_fallback_entry, | 344 url, &found_entry, &found_intercept_namespace, |
| 294 &found_fallback_namespace, | 345 &found_fallback_entry, &found_fallback_namespace, |
| 295 &ignore_found_network_namespace); | 346 &ignore_found_network_namespace); |
| 296 | 347 |
| 297 // 6.11.1 Navigating across documents, Step 10. | 348 // 6.11.1 Navigating across documents, Step 10. |
| 298 // Network namespacing doesn't apply to main resource loads, | 349 // Network namespacing doesn't apply to main resource loads, |
| 299 // and foreign entries are excluded. | 350 // and foreign entries are excluded. |
| 300 if (!found || ignore_found_network_namespace || | 351 if (!found || ignore_found_network_namespace || |
| 301 (found_entry.has_response_id() && found_entry.IsForeign()) || | 352 (found_entry.has_response_id() && found_entry.IsForeign()) || |
| 302 (found_fallback_entry.has_response_id() && | 353 (found_fallback_entry.has_response_id() && |
| 303 found_fallback_entry.IsForeign())) { | 354 found_fallback_entry.IsForeign())) { |
| 304 continue; | 355 continue; |
| 305 } | 356 } |
| 306 | 357 |
| 307 // We have a bias for hits from caches that are in use. | 358 // We have a bias for hits from caches that are in use. |
| 308 bool is_in_use = IsCacheStored(cache) && !cache->HasOneRef(); | 359 bool is_in_use = IsCacheStored(cache) && !cache->HasOneRef(); |
| 309 | 360 |
| 310 if (found_entry.has_response_id()) { | 361 if (found_entry.has_response_id() && |
| 311 found_candidate.url = url; | 362 found_intercept_namespace.is_empty()) { |
| 363 found_candidate.namespace_entry_url = GURL(); |
| 312 found_candidate.entry = found_entry; | 364 found_candidate.entry = found_entry; |
| 313 found_candidate.cache_id = cache->cache_id(); | 365 found_candidate.cache_id = cache->cache_id(); |
| 314 found_candidate.group_id = group->group_id(); | 366 found_candidate.group_id = group->group_id(); |
| 315 found_candidate.manifest_url = group->manifest_url(); | 367 found_candidate.manifest_url = group->manifest_url(); |
| 316 found_candidate.is_cache_in_use = is_in_use; | 368 found_candidate.is_cache_in_use = is_in_use; |
| 317 if (is_in_use) | 369 if (is_in_use) |
| 318 break; // We break out of the loop with this direct hit. | 370 break; // We break out of the loop with this direct hit. |
| 371 } else if (found_entry.has_response_id() && |
| 372 !found_intercept_namespace.is_empty()) { |
| 373 MaybeTakeNewNamespaceEntry( |
| 374 INTERCEPT_NAMESPACE, |
| 375 found_entry, found_intercept_namespace, is_in_use, |
| 376 &found_candidate, &found_intercept_candidate_namespace, |
| 377 cache, group); |
| 319 } else { | 378 } else { |
| 320 DCHECK(found_fallback_entry.has_response_id()); | 379 DCHECK(found_fallback_entry.has_response_id()); |
| 321 | 380 MaybeTakeNewNamespaceEntry( |
| 322 bool take_new_candidate = true; | 381 FALLBACK_NAMESPACE, |
| 323 | 382 found_fallback_entry, found_fallback_namespace, is_in_use, |
| 324 // Does the newly found entry trump our current candidate? | 383 &found_fallback_candidate, &found_fallback_candidate_namespace, |
| 325 if (found_fallback_candidate.entry.has_response_id()) { | 384 cache, group); |
| 326 // Longer namespace prefix matches win. | |
| 327 size_t found_length = | |
| 328 found_fallback_namespace.spec().length(); | |
| 329 size_t candidate_length = | |
| 330 found_fallback_candidate_namespace.spec().length(); | |
| 331 | |
| 332 if (found_length > candidate_length) { | |
| 333 take_new_candidate = true; | |
| 334 } else if (found_length == candidate_length && | |
| 335 is_in_use && !found_fallback_candidate.is_cache_in_use) { | |
| 336 take_new_candidate = true; | |
| 337 } else { | |
| 338 take_new_candidate = false; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 if (take_new_candidate) { | |
| 343 found_fallback_candidate.url = | |
| 344 cache->GetFallbackEntryUrl(found_fallback_namespace); | |
| 345 found_fallback_candidate.entry = found_fallback_entry; | |
| 346 found_fallback_candidate.cache_id = cache->cache_id(); | |
| 347 found_fallback_candidate.group_id = group->group_id(); | |
| 348 found_fallback_candidate.manifest_url = group->manifest_url(); | |
| 349 found_fallback_candidate.is_cache_in_use = is_in_use; | |
| 350 found_fallback_candidate_namespace = found_fallback_namespace; | |
| 351 } | |
| 352 } | 385 } |
| 353 } | 386 } |
| 354 | 387 |
| 355 // Found a direct hit. | 388 // Found a direct hit or an intercept namespace hit. |
| 356 if (found_candidate.entry.has_response_id()) { | 389 if (found_candidate.entry.has_response_id()) { |
| 357 delegate_ref->delegate->OnMainResponseFound( | 390 delegate_ref->delegate->OnMainResponseFound( |
| 358 url, found_candidate.entry, GURL(), AppCacheEntry(), | 391 url, found_candidate.entry, found_candidate.namespace_entry_url, |
| 359 found_candidate.cache_id, found_candidate.group_id, | 392 AppCacheEntry(), found_candidate.cache_id, found_candidate.group_id, |
| 360 found_candidate.manifest_url); | 393 found_candidate.manifest_url); |
| 361 return; | 394 return; |
| 362 } | 395 } |
| 363 | 396 |
| 364 // Found a fallback namespace. | 397 // Found a fallback namespace. |
| 365 if (found_fallback_candidate.entry.has_response_id()) { | 398 if (found_fallback_candidate.entry.has_response_id()) { |
| 366 delegate_ref->delegate->OnMainResponseFound( | 399 delegate_ref->delegate->OnMainResponseFound( |
| 367 url, AppCacheEntry(), | 400 url, AppCacheEntry(), |
| 368 found_fallback_candidate.url, | 401 found_fallback_candidate.namespace_entry_url, |
| 369 found_fallback_candidate.entry, | 402 found_fallback_candidate.entry, |
| 370 found_fallback_candidate.cache_id, | 403 found_fallback_candidate.cache_id, |
| 371 found_fallback_candidate.group_id, | 404 found_fallback_candidate.group_id, |
| 372 found_fallback_candidate.manifest_url); | 405 found_fallback_candidate.manifest_url); |
| 373 return; | 406 return; |
| 374 } | 407 } |
| 375 | 408 |
| 376 // Didn't find anything. | 409 // Didn't find anything. |
| 377 delegate_ref->delegate->OnMainResponseFound( | 410 delegate_ref->delegate->OnMainResponseFound( |
| 378 url, AppCacheEntry(), GURL(), AppCacheEntry(), kNoCacheId, 0, GURL()); | 411 url, AppCacheEntry(), GURL(), AppCacheEntry(), kNoCacheId, 0, GURL()); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 bool MockAppCacheStorage::ShouldCacheLoadAppearAsync(const AppCache* cache) { | 526 bool MockAppCacheStorage::ShouldCacheLoadAppearAsync(const AppCache* cache) { |
| 494 if (!cache) | 527 if (!cache) |
| 495 return true; | 528 return true; |
| 496 | 529 |
| 497 // If the 'stored' ref is the only ref, real storage will have to load from | 530 // If the 'stored' ref is the only ref, real storage will have to load from |
| 498 // the database. | 531 // the database. |
| 499 return IsCacheStored(cache) && cache->HasOneRef(); | 532 return IsCacheStored(cache) && cache->HasOneRef(); |
| 500 } | 533 } |
| 501 | 534 |
| 502 } // namespace appcache | 535 } // namespace appcache |
| OLD | NEW |