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 | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
6 rights reserved. | 6 rights reserved. |
7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 7 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
8 | 8 |
9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { | 475 if (params.IsSpeculativePreload() || params.IsLinkPreload()) { |
476 DEFINE_RESOURCE_HISTOGRAM("Preload."); | 476 DEFINE_RESOURCE_HISTOGRAM("Preload."); |
477 } else { | 477 } else { |
478 DEFINE_RESOURCE_HISTOGRAM(""); | 478 DEFINE_RESOURCE_HISTOGRAM(""); |
479 } | 479 } |
480 | 480 |
481 // Aims to count Resource only referenced from MemoryCache (i.e. what would be | 481 // Aims to count Resource only referenced from MemoryCache (i.e. what would be |
482 // dead if MemoryCache holds weak references to Resource). Currently we check | 482 // dead if MemoryCache holds weak references to Resource). Currently we check |
483 // references to Resource from ResourceClient and |m_preloads| only, because | 483 // references to Resource from ResourceClient and |m_preloads| only, because |
484 // they are major sources of references. | 484 // they are major sources of references. |
485 if (resource && !resource->IsAlive() && !preloads_.Contains(resource)) { | 485 if (resource && !resource->IsAlive() && !ContainsAsPreload(resource)) { |
486 DEFINE_RESOURCE_HISTOGRAM("Dead."); | 486 DEFINE_RESOURCE_HISTOGRAM("Dead."); |
487 } | 487 } |
488 } | 488 } |
489 | 489 |
| 490 bool ResourceFetcher::ContainsAsPreload(Resource* resource) const { |
| 491 auto it = preloads_.Find(PreloadKey(resource->Url(), resource->GetType())); |
| 492 return it != preloads_.end() && it->value == resource; |
| 493 } |
| 494 |
| 495 void ResourceFetcher::RemovePreload(Resource* resource) { |
| 496 auto it = preloads_.Find(PreloadKey(resource->Url(), resource->GetType())); |
| 497 if (it == preloads_.end()) |
| 498 return; |
| 499 if (it->value == resource) { |
| 500 resource->DecreasePreloadCount(); |
| 501 preloads_.erase(it); |
| 502 } |
| 503 } |
| 504 |
490 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( | 505 ResourceFetcher::PrepareRequestResult ResourceFetcher::PrepareRequest( |
491 FetchParameters& params, | 506 FetchParameters& params, |
492 const ResourceFactory& factory, | 507 const ResourceFactory& factory, |
493 const SubstituteData& substitute_data, | 508 const SubstituteData& substitute_data, |
494 unsigned long identifier, | 509 unsigned long identifier, |
495 ResourceRequestBlockedReason& blocked_reason) { | 510 ResourceRequestBlockedReason& blocked_reason) { |
496 ResourceRequest& resource_request = params.MutableResourceRequest(); | 511 ResourceRequest& resource_request = params.MutableResourceRequest(); |
497 | 512 |
498 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || | 513 DCHECK(params.Options().synchronous_policy == kRequestAsynchronously || |
499 factory.GetType() == Resource::kRaw || | 514 factory.GetType() == Resource::kRaw || |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; | 595 bool is_static_data = is_data_url || substitute_data.IsValid() || archive_; |
581 if (is_static_data) { | 596 if (is_static_data) { |
582 resource = ResourceForStaticData(params, factory, substitute_data); | 597 resource = ResourceForStaticData(params, factory, substitute_data); |
583 // Abort the request if the archive doesn't contain the resource, except in | 598 // Abort the request if the archive doesn't contain the resource, except in |
584 // the case of data URLs which might have resources such as fonts that need | 599 // the case of data URLs which might have resources such as fonts that need |
585 // to be decoded only on demand. These data URLs are allowed to be | 600 // to be decoded only on demand. These data URLs are allowed to be |
586 // processed using the normal ResourceFetcher machinery. | 601 // processed using the normal ResourceFetcher machinery. |
587 if (!resource && !is_data_url && archive_) | 602 if (!resource && !is_data_url && archive_) |
588 return nullptr; | 603 return nullptr; |
589 } | 604 } |
| 605 RevalidationPolicy policy = kLoad; |
| 606 bool preload_found = false; |
590 if (!resource) { | 607 if (!resource) { |
591 resource = | 608 resource = MatchPreload(params, factory.GetType()); |
592 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); | 609 if (resource) { |
| 610 preload_found = true; |
| 611 policy = kUse; |
| 612 // If |param| is for a blocking resource and a preloaded resource is |
| 613 // found, we may need to make it block the onload event. |
| 614 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); |
| 615 } |
593 } | 616 } |
| 617 if (!preload_found) { |
| 618 if (!resource) { |
| 619 resource = |
| 620 GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); |
| 621 } |
594 | 622 |
595 // If we got a preloaded resource from the cache for a non-preload request, | 623 policy = DetermineRevalidationPolicy(factory.GetType(), params, resource, |
596 // we may need to make it block the onload event. | 624 is_static_data); |
597 MakePreloadedResourceBlockOnloadIfNeeded(resource, params); | 625 TRACE_EVENT_INSTANT1( |
598 | 626 "blink", "ResourceFetcher::determineRevalidationPolicy", |
599 const RevalidationPolicy policy = DetermineRevalidationPolicy( | 627 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); |
600 factory.GetType(), params, resource, is_static_data); | 628 } |
601 TRACE_EVENT_INSTANT1("blink", "ResourceFetcher::determineRevalidationPolicy", | |
602 TRACE_EVENT_SCOPE_THREAD, "revalidationPolicy", policy); | |
603 | 629 |
604 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); | 630 UpdateMemoryCacheStats(resource, policy, params, factory, is_static_data); |
605 | 631 |
606 switch (policy) { | 632 switch (policy) { |
607 case kReload: | 633 case kReload: |
608 GetMemoryCache()->Remove(resource); | 634 GetMemoryCache()->Remove(resource); |
609 // Fall through | 635 // Fall through |
610 case kLoad: | 636 case kLoad: |
611 resource = CreateResourceForLoading(params, params.Charset(), factory); | 637 resource = CreateResourceForLoading(params, params.Charset(), factory); |
612 break; | 638 break; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 // If only the fragment identifiers differ, it is the same resource. | 671 // If only the fragment identifiers differ, it is the same resource. |
646 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); | 672 DCHECK(EqualIgnoringFragmentIdentifier(resource->Url(), params.Url())); |
647 RequestLoadStarted(identifier, resource, params, policy, is_static_data); | 673 RequestLoadStarted(identifier, resource, params, policy, is_static_data); |
648 document_resources_.Set( | 674 document_resources_.Set( |
649 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); | 675 MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()), resource); |
650 | 676 |
651 // Returns with an existing resource if the resource does not need to start | 677 // Returns with an existing resource if the resource does not need to start |
652 // loading immediately. If revalidation policy was determined as |Revalidate|, | 678 // loading immediately. If revalidation policy was determined as |Revalidate|, |
653 // the resource was already initialized for the revalidation here, but won't | 679 // the resource was already initialized for the revalidation here, but won't |
654 // start loading. | 680 // start loading. |
655 if (!ResourceNeedsLoad(resource, params, policy)) | 681 if (!ResourceNeedsLoad(resource, params, policy)) { |
| 682 if (policy != kUse) |
| 683 InsertAsPreloadIfNecessary(resource, params, factory.GetType()); |
656 return resource; | 684 return resource; |
| 685 } |
657 | 686 |
658 if (!StartLoad(resource)) | 687 if (!StartLoad(resource)) |
659 return nullptr; | 688 return nullptr; |
| 689 |
| 690 if (policy != kUse) |
| 691 InsertAsPreloadIfNecessary(resource, params, factory.GetType()); |
660 scoped_resource_load_tracker.resourceLoadContinuesBeyondScope(); | 692 scoped_resource_load_tracker.resourceLoadContinuesBeyondScope(); |
661 | 693 |
662 DCHECK(!resource->ErrorOccurred() || | 694 DCHECK(!resource->ErrorOccurred() || |
663 params.Options().synchronous_policy == kRequestSynchronously); | 695 params.Options().synchronous_policy == kRequestSynchronously); |
664 return resource; | 696 return resource; |
665 } | 697 } |
666 | 698 |
667 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { | 699 void ResourceFetcher::ResourceTimingReportTimerFired(TimerBase* timer) { |
668 DCHECK_EQ(timer, &resource_timing_report_timer_); | 700 DCHECK_EQ(timer, &resource_timing_report_timer_); |
669 Vector<RefPtr<ResourceTimingInfo>> timing_reports; | 701 Vector<RefPtr<ResourceTimingInfo>> timing_reports; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 if (it != resource_timing_info_map_.end()) { | 834 if (it != resource_timing_info_map_.end()) { |
803 it->value->AddRedirect(redirect_response, cross_origin); | 835 it->value->AddRedirect(redirect_response, cross_origin); |
804 } | 836 } |
805 | 837 |
806 if (resource->GetType() == Resource::kMainResource) { | 838 if (resource->GetType() == Resource::kMainResource) { |
807 DCHECK(navigation_timing_info_); | 839 DCHECK(navigation_timing_info_); |
808 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); | 840 navigation_timing_info_->AddRedirect(redirect_response, cross_origin); |
809 } | 841 } |
810 } | 842 } |
811 | 843 |
812 ResourceFetcher::RevalidationPolicy | 844 Resource* ResourceFetcher::MatchPreload(const FetchParameters& params, |
813 ResourceFetcher::DetermineRevalidationPolicy( | 845 Resource::Type type) { |
814 Resource::Type type, | 846 auto it = preloads_.Find(PreloadKey(params.Url(), type)); |
815 const FetchParameters& fetch_params, | 847 if (it == preloads_.end()) |
816 Resource* existing_resource, | 848 return nullptr; |
817 bool is_static_data) const { | |
818 const ResourceRequest& request = fetch_params.GetResourceRequest(); | |
819 | 849 |
820 if (!existing_resource) | 850 Resource* resource = it->value; |
821 return kLoad; | |
822 | 851 |
823 // If the existing resource is loading and the associated fetcher is not equal | 852 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); |
824 // to |this|, we must not use the resource. Otherwise, CSP violation may | 853 if (resource->MustRefetchDueToIntegrityMetadata(params)) |
825 // happen in redirect handling. | 854 return nullptr; |
826 if (existing_resource->Loader() && | 855 |
827 existing_resource->Loader()->Fetcher() != this) { | 856 if (params.IsSpeculativePreload()) |
828 return kReload; | 857 return resource; |
| 858 if (params.IsLinkPreload()) { |
| 859 resource->SetLinkPreload(true); |
| 860 return resource; |
829 } | 861 } |
830 | 862 |
831 // Checks if the resource has an explicit policy about integrity metadata. | 863 if (!IsReusableForPreloading(params, resource, false)) |
832 // | 864 return nullptr; |
833 // This is necessary because ScriptResource and CSSStyleSheetResource objects | 865 |
834 // do not keep the raw data around after the source is accessed once, so if | 866 resource->DecreasePreloadCount(); |
835 // the resource is accessed from the MemoryCache for a second time, there is | 867 preloads_.erase(it); |
836 // no way to redo an integrity check. | 868 return resource; |
837 // | 869 } |
838 // Thus, Blink implements a scheme where it caches the integrity information | 870 |
839 // for those resources after the first time it is checked, and if there is | 871 void ResourceFetcher::InsertAsPreloadIfNecessary(Resource* resource, |
840 // another request for that resource, with the same integrity metadata, Blink | 872 const FetchParameters& params, |
841 // skips the integrity calculation. However, if the integrity metadata is a | 873 Resource::Type type) { |
842 // mismatch, the MemoryCache must be skipped here, and a new request for the | 874 // CSP layout tests verify that preloads are subject to access checks by |
843 // resource must be made to get the raw data. This is expected to be an | 875 // seeing if they are in the `preload started` list. Therefore do not add |
844 // uncommon case, however, as it implies two same-origin requests to the same | 876 // them to the list if the load is immediately denied. |
845 // resource, but with different integrity metadata. | 877 if ((params.IsSpeculativePreload() || params.IsLinkPreload()) && |
846 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); | 878 !resource->GetResourceError().IsAccessCheck()) { |
847 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { | 879 PreloadKey key(params.Url(), type); |
848 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); | 880 if (preloads_.Find(key) == preloads_.end()) { |
849 return kReload; | 881 preloads_.insert(key, resource); |
| 882 resource->IncreasePreloadCount(); |
| 883 if (preloaded_urls_for_test_) |
| 884 preloaded_urls_for_test_->insert(resource->Url().GetString()); |
| 885 } |
850 } | 886 } |
| 887 } |
851 | 888 |
852 // If the same URL has been loaded as a different type, we need to reload. | 889 bool ResourceFetcher::IsReusableForPreloading(const FetchParameters& params, |
853 if (existing_resource->GetType() != type) { | 890 Resource* existing_resource, |
854 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch | 891 bool is_static_data) const { |
855 // We really should discard the new prefetch since the preload has more | 892 const ResourceRequest& request = params.GetResourceRequest(); |
856 // specific type information! crbug.com/379893 | |
857 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. | |
858 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " | |
859 "reloading due to type mismatch."; | |
860 return kReload; | |
861 } | |
862 | |
863 // We already have a preload going for this URL. | |
864 if (fetch_params.IsSpeculativePreload() && existing_resource->IsPreloaded()) | |
865 return kUse; | |
866 | |
867 // Do not load from cache if images are not enabled. There are two general | 893 // Do not load from cache if images are not enabled. There are two general |
868 // cases: | 894 // cases: |
869 // | 895 // |
870 // 1. Images are disabled. Don't ever load images, even if the image is cached | 896 // 1. Images are disabled. Don't ever load images, even if the image is cached |
871 // or it is a data: url. In this case, we "Reload" the image, then defer it | 897 // or it is a data: url. In this case, we "Reload" the image, then defer it |
872 // with resourceNeedsLoad() so that it never actually goes to the network. | 898 // with resourceNeedsLoad() so that it never actually goes to the network. |
873 // | 899 // |
874 // 2. Images are enabled, but not loaded automatically. In this case, we will | 900 // 2. Images are enabled, but not loaded automatically. In this case, we will |
875 // Use cached resources or data: urls, but will similarly fall back to a | 901 // Use cached resources or data: urls, but will similarly fall back to a |
876 // deferred network load if we don't have the data available without a network | 902 // deferred network load if we don't have the data available without a network |
877 // request. We check allowImage() here, which is affected by m_imagesEnabled | 903 // request. We check allowImage() here, which is affected by m_imagesEnabled |
878 // but not m_autoLoadImages, in order to allow for this differing behavior. | 904 // but not m_autoLoadImages, in order to allow for this differing behavior. |
879 // | 905 // |
880 // TODO(japhet): Can we get rid of one of these settings? | 906 // TODO(japhet): Can we get rid of one of these settings? |
881 if (existing_resource->IsImage() && | 907 if (existing_resource->IsImage() && |
882 !Context().AllowImage(images_enabled_, existing_resource->Url())) { | 908 !Context().AllowImage(images_enabled_, existing_resource->Url())) { |
883 return kReload; | 909 return false; |
884 } | 910 } |
885 | 911 |
886 // Never use cache entries for downloadToFile / useStreamOnResponse requests. | 912 // Never use cache entries for downloadToFile / useStreamOnResponse requests. |
887 // The data will be delivered through other paths. | 913 // The data will be delivered through other paths. |
888 if (request.DownloadToFile() || request.UseStreamOnResponse()) | 914 if (request.DownloadToFile() || request.UseStreamOnResponse()) |
889 return kReload; | 915 return false; |
890 | 916 |
891 // Never reuse opaque responses from a service worker for requests that are | 917 // Never reuse opaque responses from a service worker for requests that are |
892 // not no-cors. https://crbug.com/625575 | 918 // not no-cors. https://crbug.com/625575 |
893 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && | 919 if (existing_resource->GetResponse().WasFetchedViaServiceWorker() && |
894 existing_resource->GetResponse().ServiceWorkerResponseType() == | 920 existing_resource->GetResponse().ServiceWorkerResponseType() == |
895 kWebServiceWorkerResponseTypeOpaque && | 921 kWebServiceWorkerResponseTypeOpaque && |
896 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { | 922 request.GetFetchRequestMode() != WebURLRequest::kFetchRequestModeNoCORS) { |
897 return kReload; | 923 return false; |
898 } | 924 } |
899 | 925 |
900 if (!is_static_data && !existing_resource->CanReuse(fetch_params)) | 926 if (!is_static_data && !existing_resource->CanReuse(params)) |
901 return kReload; | 927 return false; |
902 | 928 |
903 // Certain requests (e.g., XHRs) might have manually set headers that require | 929 // Certain requests (e.g., XHRs) might have manually set headers that require |
904 // revalidation. In theory, this should be a Revalidate case. In practice, the | 930 // revalidation. In theory, this should be a Revalidate case. In practice, the |
905 // MemoryCache revalidation path assumes a whole bunch of things about how | 931 // MemoryCache revalidation path assumes a whole bunch of things about how |
906 // revalidation works that manual headers violate, so punt to Reload instead. | 932 // revalidation works that manual headers violate, so punt to Reload instead. |
907 // | 933 // |
908 // Similarly, a request with manually added revalidation headers can lead to a | 934 // Similarly, a request with manually added revalidation headers can lead to a |
909 // 304 response for a request that wasn't flagged as a revalidation attempt. | 935 // 304 response for a request that wasn't flagged as a revalidation attempt. |
910 // Normally, successful revalidation will maintain the original response's | 936 // Normally, successful revalidation will maintain the original response's |
911 // status code, but for a manual revalidation the response code remains 304. | 937 // status code, but for a manual revalidation the response code remains 304. |
912 // In this case, the Resource likely has insufficient context to provide a | 938 // In this case, the Resource likely has insufficient context to provide a |
913 // useful cache hit or revalidation. See http://crbug.com/643659 | 939 // useful cache hit or revalidation. See http://crbug.com/643659 |
914 if (!is_static_data && | 940 if (!is_static_data && |
915 (request.IsConditional() || | 941 (request.IsConditional() || |
916 existing_resource->GetResponse().HttpStatusCode() == 304)) { | 942 existing_resource->GetResponse().HttpStatusCode() == 304)) { |
| 943 return false; |
| 944 } |
| 945 |
| 946 if (!is_static_data && |
| 947 !params.Options().CanReuseRequest(existing_resource->Options())) { |
| 948 return false; |
| 949 } |
| 950 |
| 951 return true; |
| 952 } |
| 953 |
| 954 ResourceFetcher::RevalidationPolicy |
| 955 ResourceFetcher::DetermineRevalidationPolicy( |
| 956 Resource::Type type, |
| 957 const FetchParameters& fetch_params, |
| 958 Resource* existing_resource, |
| 959 bool is_static_data) const { |
| 960 const ResourceRequest& request = fetch_params.GetResourceRequest(); |
| 961 |
| 962 if (!existing_resource) |
| 963 return kLoad; |
| 964 |
| 965 // If the existing resource is loading and the associated fetcher is not equal |
| 966 // to |this|, we must not use the resource. Otherwise, CSP violation may |
| 967 // happen in redirect handling. |
| 968 if (existing_resource->Loader() && |
| 969 existing_resource->Loader()->Fetcher() != this) { |
917 return kReload; | 970 return kReload; |
918 } | 971 } |
919 | 972 |
920 if (!is_static_data && | 973 // Checks if the resource has an explicit policy about integrity metadata. |
921 !fetch_params.Options().CanReuseRequest(existing_resource->Options())) { | 974 // |
| 975 // This is necessary because ScriptResource and CSSStyleSheetResource objects |
| 976 // do not keep the raw data around after the source is accessed once, so if |
| 977 // the resource is accessed from the MemoryCache for a second time, there is |
| 978 // no way to redo an integrity check. |
| 979 // |
| 980 // Thus, Blink implements a scheme where it caches the integrity information |
| 981 // for those resources after the first time it is checked, and if there is |
| 982 // another request for that resource, with the same integrity metadata, Blink |
| 983 // skips the integrity calculation. However, if the integrity metadata is a |
| 984 // mismatch, the MemoryCache must be skipped here, and a new request for the |
| 985 // resource must be made to get the raw data. This is expected to be an |
| 986 // uncommon case, however, as it implies two same-origin requests to the same |
| 987 // resource, but with different integrity metadata. |
| 988 RecordSriResourceIntegrityMismatchEvent(kCheckingForIntegrityMismatch); |
| 989 if (existing_resource->MustRefetchDueToIntegrityMetadata(fetch_params)) { |
| 990 RecordSriResourceIntegrityMismatchEvent(kRefetchDueToIntegrityMismatch); |
922 return kReload; | 991 return kReload; |
923 } | 992 } |
924 | 993 |
925 // Always use preloads. | 994 // If the same URL has been loaded as a different type, we need to reload. |
926 if (existing_resource->IsPreloaded()) | 995 if (existing_resource->GetType() != type) { |
927 return kUse; | 996 // FIXME: If existingResource is a Preload and the new type is LinkPrefetch |
| 997 // We really should discard the new prefetch since the preload has more |
| 998 // specific type information! crbug.com/379893 |
| 999 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. |
| 1000 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy " |
| 1001 "reloading due to type mismatch."; |
| 1002 return kReload; |
| 1003 } |
| 1004 |
| 1005 // If |existing_resource| is not reusable as a preloaded resource, it should |
| 1006 // not be reusable as a normal resource as well. |
| 1007 if (!IsReusableForPreloading(fetch_params, existing_resource, is_static_data)) |
| 1008 return kReload; |
928 | 1009 |
929 // If resource was populated from a SubstituteData load or data: url, use it. | 1010 // If resource was populated from a SubstituteData load or data: url, use it. |
930 if (is_static_data) | 1011 if (is_static_data) |
931 return kUse; | 1012 return kUse; |
932 | 1013 |
933 // Don't reload resources while pasting. | 1014 // Don't reload resources while pasting. |
934 if (allow_stale_resources_) | 1015 if (allow_stale_resources_) |
935 return kUse; | 1016 return kUse; |
936 | 1017 |
937 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. | 1018 // WebCachePolicy::ReturnCacheDataElseLoad uses the cache no matter what. |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1078 } | 1159 } |
1079 | 1160 |
1080 int ResourceFetcher::BlockingRequestCount() const { | 1161 int ResourceFetcher::BlockingRequestCount() const { |
1081 return loaders_.size(); | 1162 return loaders_.size(); |
1082 } | 1163 } |
1083 | 1164 |
1084 int ResourceFetcher::NonblockingRequestCount() const { | 1165 int ResourceFetcher::NonblockingRequestCount() const { |
1085 return non_blocking_loaders_.size(); | 1166 return non_blocking_loaders_.size(); |
1086 } | 1167 } |
1087 | 1168 |
1088 void ResourceFetcher::PreloadStarted(Resource* resource) { | |
1089 if (preloads_.Contains(resource)) | |
1090 return; | |
1091 resource->IncreasePreloadCount(); | |
1092 | |
1093 preloads_.insert(resource); | |
1094 | |
1095 if (preloaded_urls_for_test_) | |
1096 preloaded_urls_for_test_->insert(resource->Url().GetString()); | |
1097 } | |
1098 | |
1099 void ResourceFetcher::EnableIsPreloadedForTest() { | 1169 void ResourceFetcher::EnableIsPreloadedForTest() { |
1100 if (preloaded_urls_for_test_) | 1170 if (preloaded_urls_for_test_) |
1101 return; | 1171 return; |
1102 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); | 1172 preloaded_urls_for_test_ = WTF::WrapUnique(new HashSet<String>); |
1103 | 1173 |
1104 for (const auto& resource : preloads_) | 1174 for (const auto& pair : preloads_) { |
| 1175 Resource* resource = pair.value; |
1105 preloaded_urls_for_test_->insert(resource->Url().GetString()); | 1176 preloaded_urls_for_test_->insert(resource->Url().GetString()); |
| 1177 } |
1106 } | 1178 } |
1107 | 1179 |
1108 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { | 1180 bool ResourceFetcher::IsPreloadedForTest(const KURL& url) const { |
1109 DCHECK(preloaded_urls_for_test_); | 1181 DCHECK(preloaded_urls_for_test_); |
1110 return preloaded_urls_for_test_->Contains(url.GetString()); | 1182 return preloaded_urls_for_test_->Contains(url.GetString()); |
1111 } | 1183 } |
1112 | 1184 |
1113 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { | 1185 void ResourceFetcher::ClearPreloads(ClearPreloadsPolicy policy) { |
1114 LogPreloadStats(policy); | 1186 LogPreloadStats(policy); |
1115 | 1187 |
1116 for (const auto& resource : preloads_) { | 1188 Vector<PreloadKey> keys_to_be_removed; |
| 1189 for (const auto& pair : preloads_) { |
| 1190 Resource* resource = pair.value; |
1117 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { | 1191 if (policy == kClearAllPreloads || !resource->IsLinkPreload()) { |
1118 resource->DecreasePreloadCount(); | 1192 resource->DecreasePreloadCount(); |
1119 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) | 1193 if (resource->GetPreloadResult() == Resource::kPreloadNotReferenced) |
1120 GetMemoryCache()->Remove(resource.Get()); | 1194 GetMemoryCache()->Remove(resource); |
1121 preloads_.erase(resource); | 1195 keys_to_be_removed.push_back(pair.key); |
1122 } | 1196 } |
1123 } | 1197 } |
| 1198 preloads_.RemoveAll(keys_to_be_removed); |
1124 } | 1199 } |
1125 | 1200 |
1126 void ResourceFetcher::WarnUnusedPreloads() { | 1201 void ResourceFetcher::WarnUnusedPreloads() { |
1127 for (const auto& resource : preloads_) { | 1202 for (const auto& pair : preloads_) { |
| 1203 Resource* resource = pair.value; |
1128 if (resource && resource->IsLinkPreload() && | 1204 if (resource && resource->IsLinkPreload() && |
1129 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { | 1205 resource->GetPreloadResult() == Resource::kPreloadNotReferenced) { |
1130 Context().AddConsoleMessage( | 1206 Context().AddConsoleMessage( |
1131 "The resource " + resource->Url().GetString() + | 1207 "The resource " + resource->Url().GetString() + |
1132 " was preloaded using link preload but not used within a few " | 1208 " was preloaded using link preload but not used within a few " |
1133 "seconds from the window's load event. Please make sure it " | 1209 "seconds from the window's load event. Please make sure it " |
1134 "wasn't preloaded for nothing.", | 1210 "wasn't preloaded for nothing.", |
1135 FetchContext::kLogWarningMessage); | 1211 FetchContext::kLogWarningMessage); |
1136 } | 1212 } |
1137 } | 1213 } |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 unsigned fonts = 0; | 1443 unsigned fonts = 0; |
1368 unsigned font_misses = 0; | 1444 unsigned font_misses = 0; |
1369 unsigned medias = 0; | 1445 unsigned medias = 0; |
1370 unsigned media_misses = 0; | 1446 unsigned media_misses = 0; |
1371 unsigned text_tracks = 0; | 1447 unsigned text_tracks = 0; |
1372 unsigned text_track_misses = 0; | 1448 unsigned text_track_misses = 0; |
1373 unsigned imports = 0; | 1449 unsigned imports = 0; |
1374 unsigned import_misses = 0; | 1450 unsigned import_misses = 0; |
1375 unsigned raws = 0; | 1451 unsigned raws = 0; |
1376 unsigned raw_misses = 0; | 1452 unsigned raw_misses = 0; |
1377 for (const auto& resource : preloads_) { | 1453 for (const auto& pair : preloads_) { |
| 1454 Resource* resource = pair.value; |
1378 // Do not double count link rel preloads. These do not get cleared if the | 1455 // Do not double count link rel preloads. These do not get cleared if the |
1379 // ClearPreloadsPolicy is only clearing speculative markup preloads. | 1456 // ClearPreloadsPolicy is only clearing speculative markup preloads. |
1380 if (resource->IsLinkPreload() && | 1457 if (resource->IsLinkPreload() && |
1381 policy == kClearSpeculativeMarkupPreloads) { | 1458 policy == kClearSpeculativeMarkupPreloads) { |
1382 continue; | 1459 continue; |
1383 } | 1460 } |
1384 int miss_count = | 1461 int miss_count = |
1385 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; | 1462 resource->GetPreloadResult() == Resource::kPreloadNotReferenced ? 1 : 0; |
1386 switch (resource->GetType()) { | 1463 switch (resource->GetType()) { |
1387 case Resource::kImage: | 1464 case Resource::kImage: |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 visitor->Trace(context_); | 1602 visitor->Trace(context_); |
1526 visitor->Trace(archive_); | 1603 visitor->Trace(archive_); |
1527 visitor->Trace(loaders_); | 1604 visitor->Trace(loaders_); |
1528 visitor->Trace(non_blocking_loaders_); | 1605 visitor->Trace(non_blocking_loaders_); |
1529 visitor->Trace(document_resources_); | 1606 visitor->Trace(document_resources_); |
1530 visitor->Trace(preloads_); | 1607 visitor->Trace(preloads_); |
1531 visitor->Trace(resource_timing_info_map_); | 1608 visitor->Trace(resource_timing_info_map_); |
1532 } | 1609 } |
1533 | 1610 |
1534 } // namespace blink | 1611 } // namespace blink |
OLD | NEW |