Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
| 7 | 7 |
| 8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
| 9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
| 10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 return true; | 219 return true; |
| 220 if (resource->stillNeedsLoad()) | 220 if (resource->stillNeedsLoad()) |
| 221 return true; | 221 return true; |
| 222 return request.options().synchronousPolicy == RequestSynchronously && resour ce->isLoading(); | 222 return request.options().synchronousPolicy == RequestSynchronously && resour ce->isLoading(); |
| 223 } | 223 } |
| 224 | 224 |
| 225 // Limit the number of URLs in m_validatedURLs to avoid memory bloat. | 225 // Limit the number of URLs in m_validatedURLs to avoid memory bloat. |
| 226 // http://crbug.com/52411 | 226 // http://crbug.com/52411 |
| 227 static const int kMaxValidatedURLsSize = 10000; | 227 static const int kMaxValidatedURLsSize = 10000; |
| 228 | 228 |
| 229 void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type) | 229 void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type, bool isStaticData) |
| 230 { | 230 { |
| 231 if (type == ResourceLoadingFromCache) | 231 if (type == ResourceLoadingFromCache) |
| 232 notifyLoadedFromMemoryCache(resource); | 232 notifyLoadedFromMemoryCache(resource); |
| 233 | 233 |
| 234 if (request.resourceRequest().url().protocolIsData() || context().hasSubstit uteData()) | 234 if (isStaticData) |
| 235 return; | 235 return; |
| 236 | 236 |
| 237 if (type == ResourceLoadingFromCache && !resource->stillNeedsLoad() && !m_va lidatedURLs.contains(request.resourceRequest().url())) { | 237 if (type == ResourceLoadingFromCache && !resource->stillNeedsLoad() && !m_va lidatedURLs.contains(request.resourceRequest().url())) { |
| 238 // Resources loaded from memory cache should be reported the first time they're used. | 238 // Resources loaded from memory cache should be reported the first time they're used. |
| 239 OwnPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(request.opt ions().initiatorInfo.name, monotonicallyIncreasingTime(), resource->type() == Re source::MainResource); | 239 OwnPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(request.opt ions().initiatorInfo.name, monotonicallyIncreasingTime(), resource->type() == Re source::MainResource); |
| 240 populateResourceTiming(info.get(), resource, true); | 240 populateResourceTiming(info.get(), resource, true); |
| 241 m_scheduledResourceTimingReports.append(info.release()); | 241 m_scheduledResourceTimingReports.append(info.release()); |
| 242 if (!m_resourceTimingReportTimer.isActive()) | 242 if (!m_resourceTimingReportTimer.isActive()) |
| 243 m_resourceTimingReportTimer.startOneShot(0, FROM_HERE); | 243 m_resourceTimingReportTimer.startOneShot(0, FROM_HERE); |
| 244 } | 244 } |
| 245 | 245 |
| 246 if (m_validatedURLs.size() >= kMaxValidatedURLsSize) { | 246 if (m_validatedURLs.size() >= kMaxValidatedURLsSize) { |
| 247 m_validatedURLs.clear(); | 247 m_validatedURLs.clear(); |
| 248 } | 248 } |
| 249 m_validatedURLs.add(request.resourceRequest().url()); | 249 m_validatedURLs.add(request.resourceRequest().url()); |
| 250 } | 250 } |
| 251 | 251 |
| 252 static PassRefPtr<TraceEvent::ConvertableToTraceFormat> urlForTraceEvent(const K URL& url) | 252 static PassRefPtr<TraceEvent::ConvertableToTraceFormat> urlForTraceEvent(const K URL& url) |
| 253 { | 253 { |
| 254 RefPtr<TracedValue> value = TracedValue::create(); | 254 RefPtr<TracedValue> value = TracedValue::create(); |
| 255 value->setString("url", url.string()); | 255 value->setString("url", url.string()); |
| 256 return value.release(); | 256 return value.release(); |
| 257 } | 257 } |
| 258 | 258 |
| 259 ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co nst ResourceFactory& factory) | 259 void ResourceFetcher::preCacheData(const FetchRequest& request, const ResourceFa ctory& factory, const SubstituteData& substituteData) |
| 260 { | |
| 261 const KURL& url = request.resourceRequest().url(); | |
| 262 ASSERT(url.protocolIsData() || substituteData.isValid()); | |
| 263 if ((factory.type() == Resource::MainResource && !substituteData.isValid()) || factory.type() == Resource::Raw || factory.type() == Resource::Media) | |
| 264 return; | |
| 265 | |
| 266 const String cacheIdentifier = getCacheIdentifier(); | |
| 267 if (Resource* oldResource = memoryCache()->resourceForURL(url, cacheIdentifi er)) { | |
| 268 if (!substituteData.isValid()) | |
| 269 return; | |
| 270 memoryCache()->remove(oldResource); | |
| 271 } | |
| 272 | |
| 273 WebString mimetype; | |
| 274 WebString charset; | |
| 275 RefPtr<SharedBuffer> data; | |
| 276 if (substituteData.isValid()) { | |
| 277 mimetype = substituteData.mimeType(); | |
| 278 charset = substituteData.textEncoding(); | |
| 279 data = substituteData.content(); | |
| 280 } else { | |
| 281 data = PassRefPtr<SharedBuffer>(Platform::current()->parseDataURL(url, m imetype, charset)); | |
| 282 if (!data) | |
| 283 return; | |
| 284 } | |
| 285 ResourceResponse response(url, mimetype, data->size(), charset, String()); | |
| 286 response.setHTTPStatusCode(200); | |
| 287 response.setHTTPStatusText("OK"); | |
| 288 | |
| 289 ResourcePtr<Resource> resource = factory.create(request.resourceRequest(), r equest.charset()); | |
| 290 resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad()) ; | |
| 291 resource->setOptions(request.options()); | |
| 292 // FIXME: We should provide a body stream here. | |
| 293 resource->responseReceived(response, nullptr); | |
| 294 resource->setDataBufferingPolicy(BufferData); | |
| 295 if (data->size()) | |
| 296 resource->setResourceBuffer(data); | |
| 297 resource->setIdentifier(createUniqueIdentifier()); | |
| 298 resource->setCacheIdentifier(cacheIdentifier); | |
| 299 resource->finish(); | |
| 300 memoryCache()->add(resource.get()); | |
| 301 scheduleDocumentResourcesGC(); | |
| 302 } | |
| 303 | |
| 304 ResourcePtr<Resource> ResourceFetcher::requestResource(FetchRequest& request, co nst ResourceFactory& factory, const SubstituteData& substituteData) | |
| 260 { | 305 { |
| 261 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || facto ry.type() == Resource::Raw); | 306 ASSERT(request.options().synchronousPolicy == RequestAsynchronously || facto ry.type() == Resource::Raw); |
| 262 | 307 |
| 263 context().upgradeInsecureRequest(request); | 308 context().upgradeInsecureRequest(request); |
| 264 context().addClientHintsIfNecessary(request); | 309 context().addClientHintsIfNecessary(request); |
| 265 context().addCSPHeaderIfNecessary(factory.type(), request); | 310 context().addCSPHeaderIfNecessary(factory.type(), request); |
| 266 | 311 |
| 312 bool isStaticData = request.resourceRequest().url().protocolIsData() || subs tituteData.isValid(); | |
| 313 if (isStaticData) | |
| 314 preCacheData(request, factory, substituteData); | |
| 315 | |
| 267 KURL url = request.resourceRequest().url(); | 316 KURL url = request.resourceRequest().url(); |
| 268 TRACE_EVENT1("blink", "ResourceFetcher::requestResource", "url", urlForTrace Event(url)); | 317 TRACE_EVENT1("blink", "ResourceFetcher::requestResource", "url", urlForTrace Event(url)); |
| 269 | 318 |
| 270 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(factory.type())); | 319 WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s ', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), req uest.charset().latin1().data(), request.priority(), request.forPreload(), Resour ceTypeName(factory.type())); |
| 271 | 320 |
| 272 // If only the fragment identifiers differ, it is the same resource. | 321 // If only the fragment identifiers differ, it is the same resource. |
| 273 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); | 322 url = MemoryCache::removeFragmentIdentifierIfNeeded(url); |
| 274 | 323 |
| 275 if (!url.isValid()) | 324 if (!url.isValid()) |
| 276 return nullptr; | 325 return nullptr; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 291 Vector<String> argv; | 340 Vector<String> argv; |
| 292 argv.append(Resource::resourceTypeToString(factory.type(), request.o ptions().initiatorInfo)); | 341 argv.append(Resource::resourceTypeToString(factory.type(), request.o ptions().initiatorInfo)); |
| 293 argv.append(url); | 342 argv.append(url); |
| 294 activityLogger->logEvent("blinkRequestResource", argv.size(), argv.d ata()); | 343 activityLogger->logEvent("blinkRequestResource", argv.size(), argv.d ata()); |
| 295 } | 344 } |
| 296 } | 345 } |
| 297 | 346 |
| 298 // See if we can use an existing resource from the cache. | 347 // See if we can use an existing resource from the cache. |
| 299 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCache Identifier()); | 348 ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url, getCache Identifier()); |
| 300 | 349 |
| 301 const RevalidationPolicy policy = determineRevalidationPolicy(factory.type() , request, resource.get()); | 350 const RevalidationPolicy policy = determineRevalidationPolicy(factory.type() , request, resource.get(), isStaticData); |
| 302 switch (policy) { | 351 switch (policy) { |
| 303 case Reload: | 352 case Reload: |
| 304 memoryCache()->remove(resource.get()); | 353 memoryCache()->remove(resource.get()); |
| 305 // Fall through | 354 // Fall through |
| 306 case Load: | 355 case Load: |
| 307 resource = createResourceForLoading(request, request.charset(), factory) ; | 356 resource = createResourceForLoading(request, request.charset(), factory) ; |
| 308 break; | 357 break; |
| 309 case Revalidate: | 358 case Revalidate: |
| 310 resource = createResourceForRevalidation(request, resource.get(), factor y); | 359 resource = createResourceForRevalidation(request, resource.get(), factor y); |
| 311 break; | 360 break; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 return request.options().synchronousPolicy == RequestSynchronously ? resource : nullptr; | 411 return request.options().synchronousPolicy == RequestSynchronously ? resource : nullptr; |
| 363 } | 412 } |
| 364 } | 413 } |
| 365 | 414 |
| 366 // FIXME: Temporarily leave main resource caching disabled for chromium, | 415 // FIXME: Temporarily leave main resource caching disabled for chromium, |
| 367 // see https://bugs.webkit.org/show_bug.cgi?id=107962. Before caching main | 416 // see https://bugs.webkit.org/show_bug.cgi?id=107962. Before caching main |
| 368 // resources, we should be sure to understand the implications for memory | 417 // resources, we should be sure to understand the implications for memory |
| 369 // use. | 418 // use. |
| 370 // Remove main resource from cache to prevent reuse. | 419 // Remove main resource from cache to prevent reuse. |
| 371 if (factory.type() == Resource::MainResource) { | 420 if (factory.type() == Resource::MainResource) { |
| 372 ASSERT(policy != Use || context().hasSubstituteData()); | 421 ASSERT(policy != Use || substituteData.isValid()); |
| 373 ASSERT(policy != Revalidate); | 422 ASSERT(policy != Revalidate); |
| 374 memoryCache()->remove(resource.get()); | 423 memoryCache()->remove(resource.get()); |
| 375 } | 424 } |
| 376 | 425 |
| 377 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork); | 426 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork); |
| 378 | 427 |
| 379 ASSERT(resource->url() == url.string()); | 428 ASSERT(resource->url() == url.string()); |
| 380 m_documentResources.set(resource->url(), resource); | 429 m_documentResources.set(resource->url(), resource); |
| 381 return resource; | 430 return resource; |
| 382 } | 431 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 if (resource->isCacheValidator()) { | 523 if (resource->isCacheValidator()) { |
| 475 const AtomicString& timingAllowOrigin = resource->resourceToRevalidate() ->response().httpHeaderField("Timing-Allow-Origin"); | 524 const AtomicString& timingAllowOrigin = resource->resourceToRevalidate() ->response().httpHeaderField("Timing-Allow-Origin"); |
| 476 if (!timingAllowOrigin.isEmpty()) | 525 if (!timingAllowOrigin.isEmpty()) |
| 477 info->setOriginalTimingAllowOrigin(timingAllowOrigin); | 526 info->setOriginalTimingAllowOrigin(timingAllowOrigin); |
| 478 } | 527 } |
| 479 | 528 |
| 480 if (resource->type() != Resource::MainResource || context().updateTimingInfo ForIFrameNavigation(info.get())) | 529 if (resource->type() != Resource::MainResource || context().updateTimingInfo ForIFrameNavigation(info.get())) |
| 481 m_resourceTimingInfoMap.add(resource, info.release()); | 530 m_resourceTimingInfoMap.add(resource, info.release()); |
| 482 } | 531 } |
| 483 | 532 |
| 484 ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy (Resource::Type type, const FetchRequest& fetchRequest, Resource* existingResour ce) const | 533 ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy (Resource::Type type, const FetchRequest& fetchRequest, Resource* existingResour ce, bool isStaticData) const |
| 485 { | 534 { |
| 486 const ResourceRequest& request = fetchRequest.resourceRequest(); | 535 const ResourceRequest& request = fetchRequest.resourceRequest(); |
| 487 | 536 |
| 488 if (!existingResource) | 537 if (!existingResource) |
| 489 return Load; | 538 return Load; |
| 490 | 539 |
| 491 // We already have a preload going for this URL. | 540 // We already have a preload going for this URL. |
| 492 if (fetchRequest.forPreload() && existingResource->isPreloaded()) | 541 if (fetchRequest.forPreload() && existingResource->isPreloaded()) |
| 493 return Use; | 542 return Use; |
| 494 | 543 |
| 495 // If the same URL has been loaded as a different type, we need to reload. | 544 // If the same URL has been loaded as a different type, we need to reload. |
| 496 if (existingResource->type() != type) { | 545 if (existingResource->type() != type) { |
| 497 // FIXME: If existingResource is a Preload and the new type is LinkPrefe tch | 546 // FIXME: If existingResource is a Preload and the new type is LinkPrefe tch |
| 498 // We really should discard the new prefetch since the preload has more | 547 // We really should discard the new prefetch since the preload has more |
| 499 // specific type information! crbug.com/379893 | 548 // specific type information! crbug.com/379893 |
| 500 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. | 549 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. |
| 501 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to type mismatch."); | 550 WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy r eloading due to type mismatch."); |
| 502 return Reload; | 551 return Reload; |
| 503 } | 552 } |
| 504 | 553 |
| 505 // Do not load from cache if images are not enabled. The load for this image will be blocked | 554 // Do not load from cache if images are not enabled. The load for this image will be blocked |
| 506 // in ImageResource::load. | 555 // in ImageResource::load. |
| 507 if (FetchRequest::DeferredByClient == fetchRequest.defer()) | 556 if (FetchRequest::DeferredByClient == fetchRequest.defer()) |
| 508 return Reload; | 557 return Reload; |
| 509 | 558 |
| 510 // Always use data uris. | |
| 511 // FIXME: Extend this to non-images. | |
| 512 if (type == Resource::Image && request.url().protocolIsData()) | |
| 513 return Use; | |
| 514 | |
| 515 // If a main resource was populated from a SubstituteData load, use it. | |
| 516 if (type == Resource::MainResource && context().hasSubstituteData()) | |
| 517 return Use; | |
| 518 | |
| 519 if (!existingResource->canReuse(request)) | 559 if (!existingResource->canReuse(request)) |
| 520 return Reload; | 560 return Reload; |
| 521 | 561 |
| 522 // Never use cache entries for downloadToFile / useStreamOnResponse | 562 // Never use cache entries for downloadToFile / useStreamOnResponse |
| 523 // requests. The data will be delivered through other paths. | 563 // requests. The data will be delivered through other paths. |
| 524 if (request.downloadToFile() || request.useStreamOnResponse()) | 564 if (request.downloadToFile() || request.useStreamOnResponse()) |
| 525 return Reload; | 565 return Reload; |
| 526 | 566 |
| 567 // If resource was populated from a SubstituteData load or data: url, use it . | |
| 568 if (isStaticData) | |
|
Nate Chapin
2015/08/14 20:48:46
This needs to come after downloadToFile(), since d
| |
| 569 return Use; | |
| 570 | |
| 527 // Certain requests (e.g., XHRs) might have manually set headers that requir e revalidation. | 571 // Certain requests (e.g., XHRs) might have manually set headers that requir e revalidation. |
| 528 // FIXME: In theory, this should be a Revalidate case. In practice, the Memo ryCache revalidation path assumes a whole bunch | 572 // FIXME: In theory, this should be a Revalidate case. In practice, the Memo ryCache revalidation path assumes a whole bunch |
| 529 // of things about how revalidation works that manual headers violate, so pu nt to Reload instead. | 573 // of things about how revalidation works that manual headers violate, so pu nt to Reload instead. |
| 530 if (request.isConditional()) | 574 if (request.isConditional()) |
| 531 return Reload; | 575 return Reload; |
| 532 | 576 |
| 533 // Don't reload resources while pasting. | 577 // Don't reload resources while pasting. |
| 534 if (m_allowStaleResources) | 578 if (m_allowStaleResources) |
| 535 return Use; | 579 return Use; |
| 536 | 580 |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1075 visitor->trace(m_archiveResourceCollection); | 1119 visitor->trace(m_archiveResourceCollection); |
| 1076 visitor->trace(m_loaders); | 1120 visitor->trace(m_loaders); |
| 1077 visitor->trace(m_nonBlockingLoaders); | 1121 visitor->trace(m_nonBlockingLoaders); |
| 1078 #if ENABLE(OILPAN) | 1122 #if ENABLE(OILPAN) |
| 1079 visitor->trace(m_preloads); | 1123 visitor->trace(m_preloads); |
| 1080 visitor->trace(m_resourceTimingInfoMap); | 1124 visitor->trace(m_resourceTimingInfoMap); |
| 1081 #endif | 1125 #endif |
| 1082 } | 1126 } |
| 1083 | 1127 |
| 1084 } | 1128 } |
| OLD | NEW |