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