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 |